Stell dir vor, du schreibst eine Funktion, die den Durchschnitt einer Studentennote berechnet. Was passiert, wenn du durch Null teilst (zum Beispiel, wenn es keine Noten gibt)? Versuchst du, so einen Code in die echte Welt zu bringen – und schon steht der Fehler als ungebetener Gast vor der Tür. PL/pgSQL gibt dir starke Tools, um solche Fehler zu handeln, damit dein Code stabil, sicher und angenehm zu benutzen bleibt.
Fehlerbehandlung in PL/pgSQL ermöglicht dir:
- Nachrichten zu erzeugen, die erklären, was schiefgelaufen ist.
- Die Ausführung bei kritischen Fehlern zu stoppen.
- Probleme zu loggen, damit du sie später analysieren kannst.
Die wichtigsten Message-Levels in PL/pgSQL
PL/pgSQL unterstützt mehrere Message-Levels, die dir helfen, Probleme effektiv zu diagnostizieren und zu beheben. Hier sind sie:
- NOTICE: Gibt eine Info-Nachricht aus. Praktisch fürs Debugging.
- WARNING: Hinweis auf ein mögliches Problem, das die Ausführung aber nicht stoppt.
- EXCEPTION: Kritischer Fehler, der die Ausführung abbricht (und die Kontrolle an den aufrufenden Code zurückgibt).
Message-Levels in PL/pgSQL
| Message-Level | Beschreibung |
|---|---|
NOTICE |
Info- oder Debug-Nachrichten. Beeinflusst die Ausführung nicht |
WARNING |
Warnung vor möglichen Problemen. Funktioniert wie ein Tipp |
EXCEPTION |
Schwerwiegender Fehler, der die Ausführung beendet |
Syntax vom RAISE-Befehl
Um Nachrichten zu erzeugen und Fehler zu behandeln, nutzt du das RAISE-Statement. Hier die Basissyntax:
RAISE <message-level> 'Nachrichtentext' [, Variablen...];
<message-level>—NOTICE,WARNING,EXCEPTION.'Nachrichtentext'— Beschreibung des Problems.[Variablen...]— Zusätzliche Werte, die du in die Nachricht einbauen kannst.
Beispiel 1: RAISE NOTICE verwenden
Manchmal willst du wissen, was in deiner Funktion gerade abgeht. Zum Beispiel beim Debuggen einer Schleife:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE 'Aktueller Wert von i: %', i;
END LOOP;
END
$$;
Ergebnis: Ausgabe in der Konsole von Aktueller Wert von i: 1, Aktueller Wert von i: 2 usw. bis 5.
Beispiel 2: RAISE EXCEPTION verwenden
Jetzt stell dir vor, du schreibst eine Funktion, die bei bestimmten Bedingungen mit einem Fehler abbrechen soll:
DO $$
BEGIN
IF 1 = 1 THEN
RAISE EXCEPTION 'Etwas ist schiefgelaufen!';
END IF;
END
$$;
Ergebnis: Die Ausführung wird abgebrochen und die Fehlermeldung erscheint in der Konsole.
Mit Parametern in RAISE arbeiten
Mit Parametern kannst du den Nachrichtentext personalisieren. Dafür nutzt du Platzhalter %:
Beispiel 3: Variablen in RAISE einfügen
DO $$
DECLARE
student_name TEXT := 'Ivan';
average_score NUMERIC := NULL;
BEGIN
IF average_score IS NULL THEN
RAISE EXCEPTION 'Student % hat keinen Durchschnittswert!', student_name;
END IF;
END
$$;
Ergebnis: Nachricht Student Ivan hat keinen Durchschnittswert!.
Wie du siehst, wird % durch die Variable student_name ersetzt, was die Nachricht verständlicher macht.
Eigene Fehler erzeugen
Fehler sind nicht immer nur Pech! Manchmal willst du sie absichtlich erzeugen, um deinen Code vor falschen Daten zu schützen.
Beispiel 4: Eingabewerte prüfen
Wir schreiben eine Funktion, die prüft, ob eine Zahl negativ ist, und einen Fehler wirft, wenn ja:
CREATE OR REPLACE FUNCTION check_positive(value NUMERIC)
RETURNS TEXT AS $$
BEGIN
IF value < 0 THEN
RAISE EXCEPTION 'Zahl % ist negativ!', value;
END IF;
RETURN 'Zahl ist korrekt.';
END;
$$ LANGUAGE plpgsql;
Jetzt testen wir die Funktion:
SELECT check_positive(-5);
Ergebnis: Fehlermeldung Zahl -5 ist negativ!.
Wenn du einen positiven Wert übergibst:
SELECT check_positive(10);
Ergebnis: Zahl ist korrekt.
Fehler im Kontext behandeln
Fehler erzeugen ist gut. Aber noch besser ist es, sie situationsabhängig zu behandeln. Dafür gibt es den BEGIN ... EXCEPTION-Block.
Struktur der Fehlerbehandlung
BEGIN
-- Dein Hauptcode
EXCEPTION
WHEN FEHLERTYP THEN
-- Was tun bei diesem Fehler
WHEN ANDERER_FEHLER THEN
-- Aktionen bei anderem Fehler
WHEN OTHERS THEN
-- Behandlung aller anderen Fehler
END;
Was steckt dahinter:
EXCEPTION— Schlüsselwort, das den Start des Fehlerbehandlungsblocks markiert.WHEN— Damit gibst du den konkreten Fehler an, z.B.unique_violationoderdivision_by_zero.OTHERS— Wird genutzt, um alle Fehler zu behandeln, die nicht explizit inWHEN-Blöcken stehen.
Beispiel 5: Division durch Null behandeln
Wir zeigen die Fehlerbehandlung mit einer einfachen Divisionsfunktion:
CREATE OR REPLACE FUNCTION safe_divide(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
-- Wir versuchen zu teilen
RETURN a / b;
EXCEPTION
WHEN division_by_zero THEN
RAISE WARNING 'Versuch, durch Null zu teilen. Gebe NULL zurück.';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Wir testen die Funktion:
SELECT safe_divide(10, 2); -- Erwartetes Ergebnis: 5
SELECT safe_divide(10, 0); -- Erwartetes Ergebnis: NULL und Warnung in der Konsole
Typische Fehler bei RAISE
Message-Level vergessen. Wenn du das Level vergisst, gibt PostgreSQL einen Fehler aus.
Falsch:
RAISE 'Nachricht ohne Level';
Richtig:
RAISE NOTICE 'Nachricht mit Level NOTICE';
Falsche Parameter. Wenn du % benutzt, achte darauf, dass du die nötige Anzahl an Variablen übergibst.
Falsch:
RAISE NOTICE 'Beispiel mit Parameter %';
Richtig:
RAISE NOTICE 'Beispiel mit Parameter %', 'Wert';
Zu viele Exceptions. Wenn du RAISE EXCEPTION zu oft nutzt, kann das wichtige Abläufe abbrechen. Setze es mit Bedacht ein.
Nützliche Tipps
- Sei vorsichtig mit
WHEN OTHERS. Gib möglichst konkrete Fehler an, damit du keine Fehler abfängst, die eigentlich anders behandelt werden sollten. - Nutze
RAISEfürs Debugging. Lass Fehler nie unbehandelt. - Vergiss die Performance nicht. Fehlerbehandlung kann aufwendig sein, vor allem in großen Prozeduren.
Wenn du alles richtig machst, werden deine Prozeduren stabil und halten auch unerwartete Ausfälle aus. Dein PM wird mega stolz auf dich sein!
GO TO FULL VERSION