2011-11-25 9 views
25

Voglio verificare la sintassi dei file contenenti query SQL prima che possano essere impegnati nel mio progetto CVS.controllo della sintassi postgresql senza eseguire la query

Per fare ciò, ho uno script commitinfo, ma ho difficoltà a scoprire se i comandi sql sono validi. psql non sembra avere una modalità dryrun, e la costruzione del mio tester postgresql-dialact dalla grammatica (che è nella sorgente) sembra un lungo tratto.

Gli script possono contenere più query, pertanto non è possibile avvolgere uno EXPLAIN.

Eventuali suggerimenti?

+0

ho raccontato problema con la SP sul blocco PostgreSQL non convalidato, fino alla sua non chiamata – triclosan

+7

@triclosan: si può essere interessati in ['plpgsql lint'] (https://github.com/okbob/plpgsql_lint) che risponde esattamente a questa scomposizione. Pavel Stěhule è lo sviluppatore principale. Vedi questo [post del blog] (http://okbob.blogspot.com/2011/07/plpgsql-lint.html). –

+0

Non ho molta esperienza con postgres quindi questa è probabilmente una pessima soluzione alternativa non degna di una vera risposta, ma aggiungo semplicemente una linea di immondizia alla fine dello script che so causerà un errore. Se il primo errore che colpisce è la linea dei rifiuti, posso essere ragionevolmente sicuro che il resto dello script sia ok. A differenza di una transazione, conserva i valori di sequenza e, per gli script semplici, è più veloce e più facile che scaricare un'altra utility. –

risposta

33

Recentemente ho scritto un'utility per controllare staticamente la sintassi di SQL per PostgreSQL. Sfrutta ecpg, il preprogrammatore SQL C incorporato per postgres, per verificare la sintassi SQL, quindi utilizza lo stesso parser identico a Postgres stesso.

È possibile controllare su github: http://github.com/markdrago/pgsanity. Puoi dare una leggerezza al README per avere un'idea migliore di come funziona e ottenere indicazioni su come installarlo. Ecco un breve esempio di come pgsanity può essere utilizzato:

$ 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

Sembra utile. Verificherò presto questo – RobAu

+3

Grazie per pgsanity! È davvero a portata di mano C'è un modo per usare pgsanity in systastic (https://github.com/scrooloose/syntastic)? Sarebbe davvero fantastico eseguire il controllo automaticamente quando si salva il file in vim. – while

+0

@while Scommetto che non sarebbe difficile aggiungerlo a syntastic. Non ho mai usato syntastic e non ho il vim foo per aggiungerlo da solo. Ma dal momento che pgsanity restituisce 0 in caso di successo o non zero in caso di errore, scommetto che sarebbe relativamente facile aggiungere. –

13

Un modo sarebbe quello di metterlo in una transazione che si tira indietro alla fine:

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

essere consapevoli che ci sono alcuni effetti che non possono essere il rollback, come dblink chiamate, o qualsiasi cosa scritta il file system o sequenze incrementate.

Vorrei consigliare la clonazione del database a scopo di test.

+0

Questo può essere fatto solo con una connessione attiva. Preferirei avere un controllo statico. E questo non si romperà se ho delle istruzioni BEGIN nel mio sql? – RobAu

+0

@RobAu: l'ulteriore 'BEGIN;' verrà ignorato. Verrà emesso un 'WARNING' –

+1

@RobAu: un controllo statico non funzionerà con query dinamiche. Bene: non sempre L'unica cosa che puoi fare è sandboxing e preghiera. – wildplasser

6

Sono di solito usare Mimer online SQL validator, l'unica cosa è che si controlla la sintassi SQL per SQL standard:

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

e non specifico per PostgreSQL ... Tuttavia se si scrive codice seguendo lo standard è possibile utilizzarlo e funziona bene ...

+0

Il vantaggio di ciò è che è più semplice cambiare i database. Adoro i postgres, ed è stato migliore negli ultimi anni, ma per molto tempo la sua filosofia di base è sembrata essere "Standards. Dove stiamo andando, non abbiamo bisogno di standard". – corsiKa

1

Si potrebbe semplicemente avvolgerla in SELECT 1 (<your query>) AS a WHERE 1 = 0;

Sarà fallire su convalida ma non sarà effettivamente eseguito. Ecco un esempio di piano di query:

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

Come faccio a racchiudere più istruzioni SQL in una selezione? – RobAu

+0

Puoi eseguire più istruzioni select? Oppure puoi usare i blocchi WITH all'inizio. –

2

Un meraviglioso programma di utilità per verificare la sintassi SQL: SQL Fiddle

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

0

È possibile eseguire query Iside funzione PostgreSQL e sollevano un'eccezione alla fine. Tutte le modifiche verranno ripristinate.Per esempio:

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; 

Un'altra sollution - plpgsql_check estensione (on github), la prossima incarnazione di pgpsql_lint

+0

come funzionerà per gli script SQL con più istruzioni? – RobAu

+0

è possibile scrivere un wrapper che restituisce il void e includere tutto il DML nell'ambiente di configurazione, eseguire particolari funzioni e query, quindi uscire con 'RAISE EXCEPTION'. prova google per qualche tipo di pgunit. Usano tale tecnica – shcherbak

Problemi correlati