Ce face RAISE și EXCEPTION (PL/pgSQL)
RAISE NOTICE trimite un mesaj informativ clientului, util la depanare. În textul mesajului, fiecare % este înlocuit cu următoarea valoare din listă. Nivelurile DEBUG și LOG nu se văd în psql cu setările implicite (client_min_messages = notice).
RAISE EXCEPTION oprește execuția și anulează tranzacția, ca orice eroare SQL. Cu USING poți adăuga HINT, DETAIL și un cod de eroare (ERRCODE), pe care aplicația îl poate verifica.
Un bloc BEGIN ... EXCEPTION WHEN ... THEN ... END prinde erorile din interiorul lui. Variabilele SQLERRM (mesajul) și SQLSTATE (codul) spun ce s-a întâmplat. Modificările din blocul care a eșuat sunt anulate automat.
Parametri
| Parametru | Descriere |
|---|---|
NOTICE / WARNING |
Mesaje care nu opresc codul. |
EXCEPTION |
Eroare: oprește codul (nivelul implicit dacă nu scrii nimic). |
USING HINT / DETAIL / ERRCODE |
Informații suplimentare pentru eroare. |
WHEN unique_violation / division_by_zero / OTHERS |
Ce erori prinde blocul EXCEPTION. |
Ce returnează
Nimic; mesajele apar în psql ca NOTICE:, WARNING: sau ERROR:.
Exemple
Exemplul 1: Eroare cu indiciu pentru utilizator
Linia din CONTEXT se numără de la începutul corpului (prima linie este restul liniei cu DO $$).
DO $$
DECLARE
stoc integer := 2;
BEGIN
IF stoc < 5 THEN
RAISE EXCEPTION 'Stoc insuficient: % bucăți', stoc
USING HINT = 'Comandă mai puțin sau așteaptă reaprovizionarea.';
END IF;
END
$$;
Rezultat în psql
ERROR: Stoc insuficient: 2 bucăți
HINT: Comandă mai puțin sau așteaptă reaprovizionarea.
CONTEXT: PL/pgSQL function inline_code_block line 6 at RAISE
Exemplul 2: Prinderea unei erori de cheie duplicată
DO $$
BEGIN
INSERT INTO clienti (email, nume) VALUES ('ana@exemplu.ro', 'Ana');
EXCEPTION
WHEN unique_violation THEN
RAISE NOTICE 'Clientul există deja (%): %', SQLSTATE, SQLERRM;
END
$$;
Rezultat în psql
NOTICE: Clientul există deja (23505): duplicate key value violates unique constraint "clienti_email_key"
DO
Exemplul 3: Niveluri diferite de mesaje
DO $$
BEGIN
RAISE DEBUG 'nu se vede cu setările implicite';
RAISE INFO 'import pornit';
RAISE WARNING '3 rânduri au codul poștal lipsă';
END
$$;
Rezultat în psql
INFO: import pornit
WARNING: 3 rânduri au codul poștal lipsă
DO
Greșeli frecvente
- Pui mai multe
%decât valori (sau invers): PostgreSQL refuză blocul cutoo few parameters specified for RAISEsautoo many parameters specified for RAISE. - Prinzi toate erorile cu
WHEN OTHERS THEN NULL: erorile reale dispar fără urmă. Prinde doar erorile pe care știi să le tratezi. - Folosești blocuri
EXCEPTIONîntr-o buclă cu milioane de pași: fiecare intrare în bloc creează un savepoint, ceea ce costă timp.
Comenzi înrudite
DO (bloc anonim): Rulează o singură dată un bloc de cod PL/pgSQL, fără să creeze o funcție. Util pentru scripturi de întreținere și migrări.CREATE FUNCTION (LANGUAGE plpgsql): Creează o funcție în PL/pgSQL, limbajul procedural al PostgreSQL: variabile, IF, bucle, tratarea erorilor.CREATE TRIGGER: Rulează automat o funcție la INSERT, UPDATE sau DELETE pe un tabel, de exemplu pentru a completa coloana actualizat_la sau pentru jurnal de audit.