2011-11-25 79 views
25

Quiero verificar la sintaxis de los archivos que contienen consultas sql antes de que puedan comprometerse en mi proyecto de CVS.verificación de sintaxis postgresql sin ejecutar la consulta

Para hacer eso, tengo un script de commitinfo, pero me cuesta averiguar si los comandos de sql son válidos. psql no parece tener un modo dryrun, y la construcción de mi propio postgresql-dialact tester a partir de la gramática (que está en la fuente) parece un tramo largo.

Las secuencias de comandos pueden contener varias consultas, por lo que no se puede ajustar un EXPLAIN.

¿Alguna pista?

+0

he problema relacionado con SP en el bloque de PostgreSQL no validado hasta que su llamada no – triclosan

+7

@triclosan: Puede que le interesen en ['plpgsql lint'] (https://github.com/okbob/plpgsql_lint) que trata exactamente esta falta de información. Pavel Stěhule es el desarrollador principal. Ver esta [publicación de blog] (http://okbob.blogspot.com/2011/07/plpgsql-lint.html). –

+0

No tengo mucha experiencia con postgres, por lo que esta es probablemente una mala solución que no es digna de una respuesta real, pero simplemente agrego una línea de basura al final del script que sé que causará un error. Si el primer error que golpea es la línea de basura, puedo estar razonablemente seguro de que el resto del script está bien. A diferencia de una transacción, conserva valores de secuencia, y para scripts simples es más rápido y más fácil que descargar otra utilidad. –

Respuesta

33

Recientemente escribí una utilidad para comprobar estáticamente la sintaxis de SQL para PostgreSQL. Aprovecha ecpg, el preprocesador de SQL C incorporado para postgres, para verificar la sintaxis de SQL, por lo que utiliza el mismo analizador que está incorporado en Postgres.

Puede consultarlo en github: http://github.com/markdrago/pgsanity. Puede darle un vistazo al archivo README para obtener una mejor idea de cómo funciona y para obtener instrucciones sobre cómo instalarlo. He aquí un breve ejemplo de cómo se puede utilizar pgsanity:

$ pgsanity good1.sql good2.sql bad.sql 
bad.sql: line 1: ERROR: syntax error at or near "bogus_token" 

$ find -name '*.sql' | xargs pgsanity 
./sql/bad1.sql: line 59: ERROR: syntax error at or near ";" 
./sql/bad2.sql: line 41: ERROR: syntax error at or near "insert" 
./sql/bad3.sql: line 57: ERROR: syntax error at or near "update" 
+0

Eso parece útil. Voy a comprobar en este pronto – RobAu

+3

Gracias por pgsanity! Es realmente útil. ¿Hay alguna forma de usar pgsanity en systastic (https://github.com/scrooloose/syntastic)? Sería realmente increíble ejecutar el cheque automáticamente al guardar el archivo en vim. – while

+0

@mientras apuesto que no sería difícil agregarlo a syntastic. Nunca he usado syntastic y no tengo el vim foo para agregarlo por mi cuenta. Pero dado que pgsanity devuelve un 0 en caso de éxito o un error distinto de cero en la falla, apuesto a que sería relativamente fácil de agregar. –

13

Una forma sería ponerlo en una transacción que revierte al final:

BEGIN; 
<query>; 
<query>; 
<query>; 
ROLLBACK; 

Tenga en cuenta que hay algunos efectos que no se pueden deshacer, como dblink llamadas, ni nada por escrito a el sistema de archivos o secuencias incrementales.

Aconsejaría clonar su base de datos con fines de prueba.

+0

Esto solo se puede hacer con una conexión activa. Yo preferiría tener un control estático. ¿Y esto no se romperá si tengo instrucciones BEGIN en mi sql? – RobAu

+0

@RobAu: se ignorará el 'BEGIN;' adicional. Se emitirá una 'ADVERTENCIA'. –

+1

@RobAu: una verificación estática no funcionará en las consultas dinámicas. Bueno, no siempre. Lo único que puedes hacer es sandboxing y rezando. – wildplasser

6

Normalmente soy utilizar Mimer online SQL validator, lo único es que compruebe la sintaxis SQL para SQL estándar:

  • SQL-92
  • SQL-99
  • SQL-03

y no es específico para PostgreSQL ... Sin embargo, si escribe código siguiendo el estándar, puede usarlo y funciona bien ...

+0

La ventaja de hacer esto es que hace que sea más fácil cambiar las bases de datos. Me encanta Postgres, y ha sido mejor en los últimos años, pero durante mucho tiempo su filosofía básica parecía ser "Estándares". A dónde vamos, no necesitamos estándares ". – corsiKa

1

sólo podría envolverlo en SELECT 1 (<your query>) AS a WHERE 1 = 0;

Se va a fallar en la validación, pero en realidad no se ejecutará. He aquí un ejemplo de plan de consulta:

Result (cost=0.00..0.01 rows=1 width=0) 
    One-Time Filter: false 
+0

¿Cómo envuelvo varias instrucciones SQL en una sola? – RobAu

+0

¿Puedes simplemente ejecutar múltiples instrucciones de selección? O puede usar bloques WITH al comienzo. –

2

Una maravillosa utilidad para verificar la sintaxis SQL: SQL Fiddle

soporta MySQL, Oracle, PostgreSQL, SQLite, MS SQL.

0

Puede ejecutar consultas ISIDE función de PostgreSQL y elevar una excepción en el final. Todos los cambios se revertirán.Por ejemplo:

CREATE OR REPLACE FUNCTION run_test(_sp character varying) 
    RETURNS character varying AS 
$BODY$ 
BEGIN 
    EXECUTE 'SELECT ' || _sp; 
    RAISE EXCEPTION '#OK'; 
EXCEPTION 
    WHEN others THEN 
    RETURN SQLERRM; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 

Otra sollution - plpgsql_check extensión (on github), la próxima encarnación de pgpsql_lint

+0

¿cómo funcionará esto para los scripts SQL de varias declaraciones? – RobAu

+0

puede escribir un contenedor volviendo vacío e incluir todos los DML en el entorno de configuración, ejecutar funciones y consultas particulares, luego salir con 'RAISE EXCEPTION'. prueba google por algún kinde de pgunit. Usan tal technik – shcherbak

Cuestiones relacionadas