oracle postgresql plsql plpgsql

PostgreSQL vs Oracle: comprobación de PL/pgSQL en "tiempo de compilación"



plsql plpgsql (2)

El lenguaje Plpgsql está diseñado sin verificación semántica en tiempo de compilación. No estoy seguro de cómo esta característica fue una intención o efecto secundario de la antigua implementación de plpgsql, pero con el tiempo encontramos algunas ventajas (pero con usted mencionó la desventaja).

más:

  • hay menos problemas con la dependencia entre funciones y otros objetos de base de datos. Es una solución simple de dependencia cíclica. El despliegue de las funciones de plpgsql es más simple, porque no necesita respetar la dependencia.
  • Algunos patrones con tablas temporales son posibles debido a la dependencia diferida. Es necesario, porque Postgres no admite tablas temporales globales.

Ejemplo:

BEGIN CREATE TEMP TABLE xx(a int); INSERT INTO xx VALUES(10); -- isn''t possible with compile time dependency END;

Menos:

  • No es posible una verificación profunda en tiempo de compilación (verificación de identificadores), aunque a veces es posible.

Para algunos proyectos más grandes, se debe usar una combinación de soluciones:

  • pruebas de regresión y unidad: es la base, porque algunas situaciones no se pueden verificar estáticamente, por ejemplo, SQL dinámico.
  • plpgsql_check - es externo, pero el proyecto admitido usó algunas compañías más grandes y usuarios más grandes de plpgsql. Puede aplicar una comprobación estática de la validez de los identificadores de SQL. Puede aplicar esta verificación mediante activadores DDL.

Resumen ejecutivo: PostgreSQL es increíble, pero enfrentamos muchos problemas en el trabajo debido al hecho de que pospone muchos controles en el código PL / pgSQL hasta el tiempo de ejecución. ¿Hay alguna manera de hacerlo más parecido a PL / SQL de Oracle a este respecto ?

Por ejemplo...

Intente ejecutar esto en cualquier Oracle DB:

create function foo return number as begin select a from dual; return a; end;

Oracle responderá de inmediato (es decir, en tiempo de compilación ) con:

[Error] ORA-00904: invalid identifier

Ahora prueba lo semánticamente equivalente en PostgreSQL:

CREATE OR REPLACE FUNCTION public.foo () RETURNS integer AS $body$ BEGIN select a; return a; END; $body$ LANGUAGE plpgsql;

Lo verás, desafortunadamente - ejecutar bien ... No se informa ningún error.

Pero cuando intente llamar a esta función (es decir, en tiempo de ejecución ) obtendrá:

ERROR: column "a" does not exist LINE 1: select a

¿Hay alguna manera de obligar a PostgreSQL a realizar análisis de sintaxis y verificar el tiempo de definición de la función, no en tiempo de ejecución? Tenemos toneladas de código PL / SQL en funcionamiento, que estamos migrando a PostgreSQL, pero la falta de comprobaciones en tiempo de compilación es muy dolorosa, obligándonos a realizar trabajos manuales, es decir, escribir código para probar todas las rutas de código en todas las funciones / procedimientos, que de otro modo estaban automatizados en Oracle.


Sí, este es un problema conocido.

PL / pgSQL (como cualquier otra función, excepto en SQL ) es una "caja negra" para PostgreSQL, por lo tanto, no es posible detectar errores, excepto en tiempo de ejecución.

Puedes hacer varias cosas:

  1. envuelva su función llamando a SQL consultas SQL en las instrucciones BEGIN / COMMIT para tener un mejor control sobre los errores;
  2. agregue bloques EXCEPTION a su código para capturar y rastrear errores. Sin embargo, tenga en cuenta que esto afectará el rendimiento de la función;
  3. utilice la extensión plpgsql_check , desarrollada por Pavel Stěhule, quien es uno de los principales contribuyentes al desarrollo PL / pgSQL. Supongo que eventualmente esta extensión llegará al núcleo de PostgreSQL, pero llevará algo de tiempo (ahora estamos en estado 9.4beta3);
  4. También puede consultar esta pregunta relacionada: comprobación de sintaxis postgresql sin ejecutar la consulta

Y realmente parece que tienes una gran necesidad de un marco de prueba de unidades.