CodeGym /Kurse /SQL SELF /Automatisches Logging mit Funktionen

Automatisches Logging mit Funktionen

SQL SELF
Level 52 , Lektion 3
Verfügbar

Stell dir vor, du schickst deinen Bot auf eigene Faust in die Datenbank, damit er komplexe Operationen ausführt. Früher oder später stolpert er, macht einen Fehler oder trifft auf eine unerwartete Situation. Ohne Logging bleibt er einfach stumm und du fragst dich, was schiefgelaufen ist. Automatisches Logging hilft dir dabei:

  • Fehler und Warnungen zu verfolgen.
  • Die Ursache und den Grund für Ausfälle zu verstehen.
  • Die Diagnose und Performance deines Codes zu verbessern.

Mit automatischem Logging baust du dir eine "Blackbox", die Events in der Datenbank festhält und dir hilft, Fehler zu finden – fast wie ein Top-Detektiv.

Automatisches Logging mit Funktionen erstellen

  1. Log-Tabelle definieren

Um Fehler zu loggen, brauchen wir einen Speicherort. Wir haben die Tabelle error_log schon in der letzten Vorlesung angelegt:

CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,                 -- Einzigartige ID des Eintrags
    error_message TEXT NOT NULL,           -- Fehlermeldung
    error_time TIMESTAMP DEFAULT NOW(),    -- Zeitpunkt des Fehlers
    function_name TEXT                     -- Name der Funktion, die den Fehler ausgelöst hat
);

Diese Tabelle hat alles, was wir zum Fehler-Logging brauchen: Fehlermeldung, Zeitpunkt und die Funktion, aus der der Fehler kam.

  1. Funktion zum Schreiben ins Log erstellen

Der nächste Schritt: Wir bauen eine universelle Funktion, die Fehler in die error_log-Tabelle schreibt. Diese Funktion rufen wir immer dann auf, wenn wir einen Fehler festhalten wollen.

CREATE OR REPLACE FUNCTION log_error(p_error_message TEXT, p_function_name TEXT)
RETURNS VOID AS $$
BEGIN
    INSERT INTO error_log (error_message, function_name)
    VALUES (p_error_message, p_function_name);
    -- Meldung über erfolgreiches Logging
    RAISE NOTICE 'Fehler geloggt: %', p_error_message;
END;
$$ LANGUAGE plpgsql;

Schauen wir uns den Code an:

  1. p_error_message und p_function_name sind die Parameter der Funktion, die die Fehlermeldung und den Namen der aufrufenden Funktion aufnehmen.
  2. INSERT INTO error_log fügt einen Eintrag in die Tabelle ein.
  3. RAISE NOTICE gibt eine Meldung in der Konsole aus, damit der Entwickler über das Logging informiert ist.

Damit haben wir die erste Aufgabe gelöst: Wir können Fehler mit minimalem Aufwand in unsere Tabelle schreiben.

Die Funktion log_error in echten Aufgaben nutzen

Beispiel 1: Fehler beim Teilen durch Null loggen

Wir bauen eine Funktion, die eine einfache Division macht, aber einen Fehler loggt, wenn der Nenner 0 ist.

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    IF b = 0 THEN
        -- Logging-Funktion aufrufen
        PERFORM log_error('Division durch Null versucht!', 'divide_numbers');
        -- Exception werfen
        RAISE EXCEPTION 'Division durch Null ist nicht erlaubt.';
    END IF;

    -- Division ausführen
    result := a / b;
    RETURN result;
END;
$$ LANGUAGE plpgsql;
  • Wenn der Nenner 0 ist, wird die Funktion log_error aufgerufen und der Fehler in die Tabelle geschrieben.
  • Nach dem Logging wird mit RAISE EXCEPTION eine Exception geworfen, damit der User Bescheid weiß.

Beispielaufruf:

SELECT divide_numbers(10, 0);

Ergebnis:

  • Der Aufruf dieser Funktion mit Division durch Null schreibt einen Fehler in die error_log-Tabelle.
  • Der User sieht die Fehlermeldung in seiner Konsole.

Beispiel 2: Logging beim Einfügen ungültiger Daten

Hier ein Beispiel mit einer Funktion, die einen neuen Studenten in die Tabelle students einfügt. Wenn der Name leer ist, loggen wir das Event und brechen ab.

CREATE OR REPLACE FUNCTION add_student(p_name TEXT)
RETURNS VOID AS $$
BEGIN
    IF p_name IS NULL OR p_name = '' THEN
        PERFORM log_error('Studentenname muss angegeben werden!', 'add_student');
        RAISE EXCEPTION 'Studentenname darf nicht leer sein.';
    END IF;

    INSERT INTO students (name) VALUES (p_name);
END;
$$ LANGUAGE plpgsql;

Beispielaufruf:

SELECT add_student('');

Wenn wir versuchen, einen Studenten ohne Namen hinzuzufügen, erstellt die Funktion einen Eintrag in error_log mit der passenden Meldung.

Beispiel 3: Logging von Warnungen

Manchmal muss man nicht gleich eine Exception werfen. Es reicht, eine Warnung zu loggen. Wir machen eine Funktion, die das Alter eines Studenten prüft:

CREATE OR REPLACE FUNCTION check_age(p_age INT)
RETURNS VOID AS $$
BEGIN
    IF p_age < 18 THEN
        -- Warnung loggen, aber nicht abbrechen
        PERFORM log_error('Studentenalter ist unter 18.', 'check_age');
        RAISE NOTICE 'Warnung: Studentenalter ist unter 18.';
    END IF;

    RAISE NOTICE 'Altersprüfung bestanden.';
END;
$$ LANGUAGE plpgsql;

Beispielaufruf:

SELECT check_age(16);

Ergebnis:

  • Warnung wird in die error_log-Tabelle geschrieben.
  • In der Konsole gibt es eine Info, dass das Alter unter 18 ist.

Logging und Exception-Handling

Lass uns Logging und Exception-Handling in einer etwas komplexeren Funktion kombinieren. Stell dir vor, wir sollen die Noten der Studenten in der Tabelle grades neu berechnen. Wenn es bei einem Studenten nicht klappt, wird der Fehler geloggt, aber die Operation läuft weiter.

CREATE OR REPLACE FUNCTION recalculate_grades()
RETURNS VOID AS $$
DECLARE
    student RECORD;
BEGIN
    FOR student IN SELECT * FROM students LOOP
        BEGIN
            -- Beispielaufgabe: Noten des Studenten updaten
            UPDATE grades SET final_grade = final_grade + 1
            WHERE student_id = student.id;

            RAISE NOTICE 'Noten für Studenten % aktualisiert', student.name;
        EXCEPTION WHEN OTHERS THEN
            -- Fehler loggen und weitermachen
            PERFORM log_error('Konnte Noten für Studenten ' || student.name || ' nicht aktualisieren', 'recalculate_grades');
        END;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

Beispielaufruf:

SELECT recalculate_grades();

Mit diesem Ansatz wird deine Funktion viel robuster, weil Fehler einzeln geloggt werden und die Verarbeitung für alle Daten nicht gestoppt wird.

2
Aufgabe
SQL SELF, Level 52, Lektion 3
Gesperrt
Fehlerprotokollierung bei Berechnungen
Fehlerprotokollierung bei Berechnungen
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION