Immagina di scrivere una funzione che calcola la media dei voti di uno studente. Cosa succede se provi a dividere per zero (tipo, se non ci sono voti)? Se mandi in produzione un codice così, l’errore ti salta subito addosso come un ninja. PL/pgSQL ti dà strumenti potenti per gestire questi errori, rendendo il tuo codice robusto, sicuro e piacevole da usare.
La gestione degli errori in PL/pgSQL permette di:
- Generare messaggi che spiegano cosa è andato storto.
- Interrompere l’esecuzione del codice in caso di errori critici.
- Loggare i problemi per analizzarli dopo.
Livelli principali dei messaggi in PL/pgSQL
PL/pgSQL supporta diversi livelli di messaggi che aiutano gli sviluppatori a diagnosticare e risolvere i problemi in modo efficace. Eccoli qui:
- NOTICE: mostra un messaggio informativo. Utile per il debug.
- WARNING: avvisa di un possibile problema, ma non ferma il programma.
- EXCEPTION: errore critico che interrompe l’esecuzione del programma (e restituisce il controllo al codice chiamante).
Livelli dei messaggi in PL/pgSQL
| Livello del messaggio | Descrizione |
|---|---|
NOTICE |
Messaggi informativi o di debug. Non influisce sull’esecuzione |
WARNING |
Avviso su possibili problemi. Funziona come suggerimento |
EXCEPTION |
Errore serio che termina l’esecuzione del programma |
Sintassi del comando RAISE
Per generare messaggi e gestire errori si usa l’istruzione RAISE. Ecco la sintassi base:
RAISE <livello del messaggio> 'testo del messaggio' [, variabili...];
<livello del messaggio>—NOTICE,WARNING,EXCEPTION.'testo del messaggio'— descrizione del problema.[variabili...]— valori extra che puoi inserire nel messaggio.
Esempio 1: uso di RAISE NOTICE
A volte è importante sapere cosa succede dentro la tua funzione. Tipo, per debuggare un ciclo:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE 'Valore attuale di i: %', i;
END LOOP;
END
$$;
Risultato: Output in console delle righe Valore attuale di i: 1, Valore attuale di i: 2 e così via fino a 5.
Esempio 2: uso di RAISE EXCEPTION
Ora immagina di scrivere una funzione che deve terminare con errore in certe condizioni:
DO $$
BEGIN
IF 1 = 1 THEN
RAISE EXCEPTION 'Qualcosa è andato storto!';
END IF;
END
$$;
Risultato: l’esecuzione si interrompe e il messaggio di errore appare in console.
Lavorare con i parametri in RAISE
Usando i parametri puoi personalizzare il testo del messaggio. Per questo si usano i placeholder %:
Esempio 3: inserire variabili in RAISE
DO $$
DECLARE
student_name TEXT := 'Ivan';
average_score NUMERIC := NULL;
BEGIN
IF average_score IS NULL THEN
RAISE EXCEPTION 'Lo studente % non ha una media!', student_name;
END IF;
END
$$;
Risultato: messaggio Lo studente Ivan non ha una media!.
Come vedi, % viene sostituito dalla variabile student_name, rendendo il messaggio più chiaro.
Generare errori personalizzati
Gli errori non sono solo sfiga! A volte devi crearli apposta per proteggere il codice da dati sbagliati.
Esempio 4: controllo dei valori in input
Scriviamo una funzione che controlla il valore di un numero e lancia un errore se è negativo:
CREATE OR REPLACE FUNCTION check_positive(value NUMERIC)
RETURNS TEXT AS $$
BEGIN
IF value < 0 THEN
RAISE EXCEPTION 'Il numero % è negativo!', value;
END IF;
RETURN 'Numero corretto.';
END;
$$ LANGUAGE plpgsql;
Ora testiamo la funzione:
SELECT check_positive(-5);
Risultato: messaggio di errore Il numero -5 è negativo!.
Se invece passi un valore positivo:
SELECT check_positive(10);
Risultato: Numero corretto.
Gestione degli errori nel contesto
Bello saper generare errori. Ma ancora meglio — gestirli a seconda della situazione. Per questo si usa il blocco BEGIN ... EXCEPTION.
Struttura della gestione degli errori
BEGIN
-- Il tuo codice principale
EXCEPTION
WHEN TIPO_ERRORE THEN
-- Cosa fare in caso di errore
WHEN ALTRO_ERRORE THEN
-- Azioni per un altro errore
WHEN OTHERS THEN
-- Gestione di tutti gli altri errori
END;
Spieghiamo i componenti:
EXCEPTION— parola chiave che indica l’inizio del blocco di gestione degli errori.WHEN— ti permette di specificare il tipo di errore da gestire, tipounique_violationodivision_by_zero.OTHERS— usato per gestire tutti gli errori non specificati nei blocchiWHEN.
Esempio 5: gestione della divisione per zero
Vediamo la gestione di un errore con un esempio semplice di funzione di divisione:
CREATE OR REPLACE FUNCTION safe_divide(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
-- Proviamo a dividere
RETURN a / b;
EXCEPTION
WHEN division_by_zero THEN
RAISE WARNING 'Tentativo di divisione per zero. Restituisco NULL.';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Testiamo la funzione:
SELECT safe_divide(10, 2); -- Risultato atteso: 5
SELECT safe_divide(10, 0); -- Risultato atteso: NULL e avviso in console
Errori tipici usando RAISE
Dimenticare il livello del messaggio. Se ti scordi di specificare il livello, PostgreSQL ti dà errore.
Sbagliato:
RAISE 'Messaggio senza livello';
Corretto:
RAISE NOTICE 'Messaggio con livello NOTICE';
Parametri sbagliati. Se usi %, assicurati di passare il numero giusto di variabili.
Sbagliato:
RAISE NOTICE 'Esempio con parametro %';
Corretto:
RAISE NOTICE 'Esempio con parametro %', 'valore';
Interruzioni eccessive. Usare troppo RAISE EXCEPTION può bloccare operazioni importanti. Usalo con testa.
Consigli utili
- Occhio al blocco
WHEN OTHERS. Se puoi, specifica errori precisi per non catturare errori che andrebbero gestiti diversamente. - Usa
RAISEper il debug. Non lasciare mai errori non gestiti. - Non dimenticare le performance. La gestione degli errori può essere pesante, soprattutto in procedure grandi.
Se fai tutto giusto, le tue procedure saranno solide e sopravviveranno anche ai crash più assurdi. Il PM sarà super fiero di te!
GO TO FULL VERSION