Usted mismo puso en negrita la oración clave en el manual:
Todo el cuerpo de una función SQL se analiza antes de que se ejecute.
Lea también sobre La etapa del analizador en el manual.
Consta de dos partes principales:el parser y el proceso de transformación . Citando el manual:
el proceso de transformación toma el árbol devuelto por el analizador como entrada y realiza la interpretación semántica necesaria para comprender a qué tablas, funciones y operadores hace referencia la consulta.
Si una función SQL contiene estos comandos:
CREATE TABLE foo (...);
INSERT INTO foo VALUES(...);
Ambas declaraciones se planifican prácticamente al mismo tiempo (basadas en la misma instantánea de los catálogos del sistema). Por lo tanto, INSERT
no se puede ver la tabla "foo" presumiblemente creada con el anterior CREATE
dominio. Eso crea uno de los siguientes problemas :
-
Si no hay otro tabla llamada "foo" en su
search_patch
(todavía), Postgres se queja al intentar crear la función:ERROR: relation "foo" does not exist
-
Si ya existe otra tabla llamada "foo" en su
search_patch
(y no usa nombres de columnas en conflicto), Postgres planificará elINSERT
en base a esa tabla preexistente. Por lo general, eso da como resultado un error en el momento de la ejecución , si algún valor causa conflictos en la tabla (¡incorrecta!). O, con un poco de mala suerte, ¡incluso podría escribir en esa tabla sin mensaje de error! Bicho muy astuto.
Eso no puede suceder con un PL/pgSQL porque trata los comandos SQL como sentencias preparadas, planificadas y ejecutadas secuencialmente . Entonces cada declaración puede ver objetos creados en declaraciones anteriores.
En consecuencia, las declaraciones que nunca se visitan ni siquiera se planifican, a diferencia de las funciones SQL. Y el plan de ejecución de las declaraciones se puede almacenar en caché dentro de la misma sesión, también a diferencia de las funciones SQL. Lea los detalles sobre el almacenamiento en caché del plan en funciones PL/pgSQL en el manual aquí.
Cada enfoque tiene ventajas para algunos casos de uso. Lectura adicional:
- Diferencia entre lenguaje sql y lenguaje plpgsql en funciones de PostgreSQL