PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Por que as funções PL/pgSQL podem ter efeito colateral, enquanto as funções SQL não podem?


Você mesmo colocou em negrito a frase-chave no manual:

Todo o corpo de uma função SQL é analisado antes de ser executado.

Leia também sobre O estágio do analisador no manual.

Ele consiste em duas partes principais:o parser e o processo de transformação . Citando o manual:

o processo de transformação pega a árvore devolvida pelo analisador como entrada e faz a interpretação semântica necessária para entender quais tabelas, funções e operadores são referenciados pela consulta.

Se uma função SQL contém estes comandos:
CREATE TABLE foo (...);
INSERT INTO foo VALUES(...);

Ambas as instruções são planejadas praticamente ao mesmo tempo (com base no mesmo instantâneo dos catálogos do sistema). Portanto, o INSERT não pode ver a tabela "foo" presumivelmente criada com o CREATE anterior comando. Isso cria um dos seguintes problemas :

  1. Se não houver outro tabela chamada "foo" em seu search_patch (ainda), o Postgres reclama ao tentar criar a função:
    ERROR:  relation "foo" does not exist
    

  2. Se outra tabela chamada "foo" já existir em seu search_patch (e você não usa nomes de colunas conflitantes), o Postgres planejará o INSERT com base nessa tabela pré-existente. Normalmente, isso resulta em um erro no tempo de execução , se algum valor causar conflitos na tabela (errada!). Ou, com algum azar, pode até gravar nessa tabela sem mensagem de erro! Bug muito sorrateiro.

Isso não pode acontecer com um PL/pgSQL função, porque trata comandos SQL como instruções preparadas, planejadas e executadas sequencialmente . Assim, cada instrução pode ver objetos criados em instruções anteriores.

Conseqüentemente, as instruções que nunca são visitadas nunca são planejadas - ao contrário das funções SQL. E o plano de execução para instruções pode ser armazenado em cache na mesma sessão - também diferente das funções SQL. Leia detalhes sobre o cache de planos em funções PL/pgSQL no manual aqui.
Cada abordagem tem vantagens para alguns casos de uso. Leitura adicional:
  • Diferença entre linguagem sql e linguagem plpgsql nas funções do PostgreSQL