2014-10-13 22 views
6

Sommario esecutivo: PostgreSQL è sorprendente, ma ci troviamo di fronte a molti problemi al lavoro dovuti al fatto che posticipa molti controlli sul codice PL/pgSQL fino al runtime . C'è un modo per renderlo più simile al PL/SQL di Oracle a questo riguardo?PostgreSQL vs Oracle: controllo "in fase di compilazione" di PL/pgSQL

Per esempio ...

Prova l'esecuzione di questo in qualsiasi Oracle DB:

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

Oracle immediatamente (cioè a tempo di compilazione !) Risponde con:

[Error] ORA-00904: invalid identifier 

Ora prova la cosa semanticamente equivalente in PostgreSQL:

Lo vedrete sfortunatamente! - Esegui bene ... Nessun errore è segnalato.

Ma quando poi si tenta di chiamare questa funzione (cioè a runtime) si otterrà:

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

C'è un modo per forzare PostgreSQL per eseguire l'analisi della sintassi e il controllo in fase di definizione di funzione - non in fase di esecuzione? Abbiamo tonnellate di codice PL/SQL legacy al lavoro, che stiamo trasferendo a PostgreSQL - ma la mancanza dei controlli in fase di compilazione è molto doloroso, costringendoci a fare il lavoro manuale - cioè scrivere codice per testare tutti i percorsi di codice in tutti funzioni/procedure, altrimenti automatizzate in Oracle.

risposta

7

Sì, questo è un problema noto.

PL/pgSQL (come qualsiasi altra funzione, ad eccezione di SQL) è una "scatola nera" per PostgreSQL, pertanto non è realmente possibile rilevare errori tranne in fase di esecuzione.

È possibile fare diverse cose:

  1. avvolgere la funzione di chiamata SQL query in BEGIN/COMMIT dichiarazioni in modo da avere un migliore controllo sulle errori;
  2. aggiungi EXCEPTION blocks al tuo codice per rilevare e tenere traccia degli errori. Si noti, tuttavia, che ciò influirà sulle prestazioni della funzione;
  3. utilizzare plpgsql_check extension, sviluppato da Pavel Stěhule, che è uno dei principali contributori allo sviluppo di PL/pgSQL. Suppongo che alla fine questa estensione diventerà il nucleo di PostgreSQL, ma ci vorrà del tempo (ora siamo nello stato 9.4beta3);
  4. Si potrebbe anche prendere in considerazione la questione relativa: postgresql syntax check without running the query

e sembra davvero come se fossi in un enorme bisogno di un quadro di unit testing.

+2

In tema di test, suggerirei immediatamente il poster originale a http://pgtap.org/ e rendere la sua vita * molto * più facile. –

4

Il linguaggio Plpgsql è progettato senza controllo della semantica in fase di compilazione. Non sono sicuro di come questa funzione sia stata un'intenzione o un effetto collaterale della vecchia implementazione di plpgsql, ma nel tempo abbiamo trovato alcuni vantaggi (ma con voi avete menzionato lo svantaggio).

più:

  • ci sono meno problemi con la dipendenza tra le funzioni e gli altri oggetti del database. È una soluzione semplice di dipendenza ciclica. La distribuzione delle funzioni di plpgsql è più semplice, perché non è necessario rispettare la dipendenza.
  • Alcuni modelli con tabelle temporanee sono possibili a causa della dipendenza pigra. È necessario, perché Postgres non supporta tabelle temporanee globali.

Esempio:

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

Minus:

  • ci sono possibili una fase di compilazione profondo di controllo (identificatori di controllo), anche se è possibile volte.

Per alcuni progetti più grandi deve essere utilizzato un mix di soluzioni:

  • test regresso e di unità - è di base, perché alcuni situazione non può essere verificata in modo statico - SQL dinamico per esempio.
  • plpgsql_check - è esterno, ma il progetto supportato ha utilizzato società più grandi e utenti plpgsql più grandi. Può imporre un controllo statico della validità degli identificatori SQL. È possibile applicare questo controllo con trigger DDL.