CodeGym /Corsi /SQL SELF /Gestione degli errori: RAISE EXCEPTION

Gestione degli errori: RAISE EXCEPTION

SQL SELF
Livello 52, Lezione 0
Disponibile

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:

  1. Generare messaggi che spiegano cosa è andato storto.
  2. Interrompere l’esecuzione del codice in caso di errori critici.
  3. 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, tipo unique_violation o division_by_zero.
  • OTHERS — usato per gestire tutti gli errori non specificati nei blocchi WHEN.

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

  1. Occhio al blocco WHEN OTHERS. Se puoi, specifica errori precisi per non catturare errori che andrebbero gestiti diversamente.
  2. Usa RAISE per il debug. Non lasciare mai errori non gestiti.
  3. 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!

2
Compito
SQL SELF, livello 52, lezione 0
Bloccato
Gestione della divisione per zero
Gestione della divisione per zero
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION