CodeGym /Kurse /SQL SELF /Fehler-Logging: Logging-Level und Nachrichtenformat

Fehler-Logging: Logging-Level und Nachrichtenformat

SQL SELF
Level 55 , Lektion 2
Verfügbar

Wir sind jetzt wie geheime Agenten – unsere Funktionen und Prozeduren führen Missionen aus: sie verarbeiten Daten, machen Berechnungen oder zaubern einfach ein bisschen Magie in der Datenbank. Aber wie merkt man, wenn etwas schief läuft? Wie findet man heraus, an welcher Stelle das "Massagebad für Daten" kaputt gegangen ist? Hier kommen Logging und Fehlerbehandlung ins Spiel.

Erinnerst du dich, wir haben schon angefangen zu schauen, wie man in PostgreSQL und PL/pgSQL "kommuniziert" und Logs schreibt:

  • RAISE NOTICE: entspannter, freundlicher Ton – "Hey, alles okay hier, aber vielleicht willst du mal draufschauen".
  • RAISE WARNING: etwas lauter – "Uff, hier ist was komisch, vielleicht solltest du mal reinschauen".
  • RAISE EXCEPTION: Panik-Sirene – "STOP! Der Algorithmus ist in Gefahr! Wir haben die Ausführung gestoppt, damit nicht alles den Bach runtergeht".

Jedes dieser Level hat seinen eigenen Zweck, und es ist wichtig, das richtige auszuwählen.

So sehen diese Nachrichten im Code aus:

DO $$
BEGIN
    -- Level NOTICE (alles okay, nur eine Info)
    RAISE NOTICE 'Nur eine Info: Datenverarbeitung gestartet';

    -- Level WARNING (etwas Verdächtiges)
    RAISE WARNING 'Warnung: Datenformat in der Spalte könnte falsch sein';

    -- Level EXCEPTION (kritischer Fehler)
    RAISE EXCEPTION 'Fehler: Eingabewert ist ungültig!';
END $$;

Wann verwenden:

  • RAISE NOTICE – für Debugging und entspannte Infos.
  • RAISE WARNING – um auf potenziell falsche Daten hinzuweisen.
  • RAISE EXCEPTION – wenn kritische Fehler auftreten, bei denen die Funktion gestoppt werden muss.

Fehlerbehandlung mit RAISE EXCEPTION

RAISE EXCEPTION ist dein Not-Aus. Wenn etwas schief läuft, kannst du die Ausführung der Funktion stoppen und eine Fehlermeldung ausgeben.

Noch mal zur Erinnerung, die Basis-Nutzung sieht so aus:

RAISE EXCEPTION 'Deine Fehlermeldung';

Aber um die Nachrichten informativer zu machen, kannst du Variablen verwenden:

DECLARE
    input_value INTEGER;
BEGIN
    input_value := NULL;

    IF input_value IS NULL THEN
        RAISE EXCEPTION 'Fehler: Eingabewert ist NULL. Erwartet wurde ein INTEGER';
    END IF;
END;

Nachrichten formatieren

Du kannst Variablen direkt in den Nachrichtentext einbauen:

DECLARE
    var1 TEXT := 'Daten';
    var2 INTEGER := 42;
BEGIN
    RAISE EXCEPTION 'Fehler bei der Verarbeitung von % mit ID %', var1, var2;
END;

Ausgabe: Fehler bei der Verarbeitung von Daten mit ID 42.

Beispiel: Datenvalidierung

Stell dir vor, du hast eine Prozedur, die das Alter einer Person entgegennimmt. Wenn das Alter negativ ist, macht es Sinn, einen Fehler zu werfen:

CREATE OR REPLACE FUNCTION validate_age(age INTEGER)
RETURNS VOID AS $$
BEGIN
    IF age < 0 THEN
        RAISE EXCEPTION 'Alter darf nicht negativ sein: %', age;
    END IF;
END;
$$ LANGUAGE plpgsql;

-- Funktionsaufruf
SELECT validate_age(-5);  -- Wirft einen Fehler

Informieren mit RAISE NOTICE

Wenn RAISE EXCEPTION die Sirene ist, dann ist RAISE NOTICE ein freundschaftliches Schulterklopfen. Mit diesem Level kannst du Kommentare einbauen, damit man versteht, was in der Funktion passiert.

Wann RAISE NOTICE verwenden:

  • Debug-Infos ausgeben (z.B. aktueller Stand von Variablen).
  • Nachricht über den Start eines Schritts oder das Ergebnis einer Berechnung.

Beispiel: Info-Nachrichten

CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount_rate NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    final_price NUMERIC;
BEGIN
    RAISE NOTICE 'Preis vor Rabatt: %', price;
    RAISE NOTICE 'Rabatt-Satz: %', discount_rate;

    final_price := price - (price * discount_rate);

    RAISE NOTICE 'Endpreis: %', final_price;

    RETURN final_price;
END;
$$ LANGUAGE plpgsql;

-- Funktionsaufruf
SELECT calculate_discount(100, 0.2);
-- Gibt aus:
-- NOTICE: Preis vor Rabatt: 100
-- NOTICE: Rabatt-Satz: 0.2
-- NOTICE: Endpreis: 80

Praxis: Planung und Logging

Angenommen, du hast eine komplexe Datenverarbeitungsprozedur und willst wissen, an welchem Schritt sie gerade ist:

CREATE OR REPLACE FUNCTION process_data_step_by_step()
RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Schritt 1: Datenvorbereitung';
    -- Deine Logik für den ersten Schritt

    RAISE NOTICE 'Schritt 2: Datenvalidierung';
    -- Deine Logik für den zweiten Schritt

    RAISE NOTICE 'Schritt 3: Daten speichern';
    -- Deine Logik für den dritten Schritt
END;
$$ LANGUAGE plpgsql;

-- Funktionsaufruf
SELECT process_data_step_by_step();
-- Im Log sieht man die Schritte nacheinander

Noch ein Beispiel. Stell dir einen Shop vor, der Rabatte nur für Bestellungen über einem bestimmten Betrag anbietet:

CREATE OR REPLACE FUNCTION apply_discount(order_amount NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    IF order_amount < 50 THEN
        RAISE EXCEPTION 'Fehler: Bestellwert muss mindestens 50 sein, aktueller Wert: %', order_amount;
    END IF;

    RETURN order_amount * 0.9;  -- 10% Rabatt anwenden
END;
$$ LANGUAGE plpgsql;

-- Funktionsaufruf
SELECT apply_discount(30);  -- Fehler: Bestellwert muss mindestens 50 sein

Typische Fehler

Fehler 1: Logging von Nachrichten ohne Parameter.

Sieht nicht sehr hilfreich aus, vor allem in großen Prozeduren:

RAISE NOTICE 'Fehler ist aufgetreten';  -- Warum? Wo? Wie?

Empfehlung: Immer Kontext hinzufügen:

RAISE NOTICE 'Fehler in Funktion process_data(): Eingabewert: %', input_value;

Fehler 2: RAISE EXCEPTION verwenden, wo RAISE WARNING reichen würde.

Wenn du zu viele Exceptions wirfst, wird der Code bei jedem kleinen Problem abgebrochen, was die Datenverarbeitung erschwert.

Tipp: Logging-Level bewusst einsetzen. Für Debugging NOTICE, für kritische Fälle EXCEPTION.

Fehler 3: Logging komplett weglassen.

Das ist wie Schlüssel im dunklen Zimmer suchen. Ohne Logs wird das Debuggen von komplexen Prozessen fast unmöglich.

Tipp: Füge RAISE NOTICE an den wichtigsten Stellen in der Funktion ein, besonders wenn sie groß und komplex ist.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION