Bevor wir richtig loslegen, lass uns kurz auf die häufigsten Fehler und Stolpersteine schauen, die dir begegnen können. Fehler in SQL sind echt der Schmerz jedes Devs – und meistens tauchen sie genau dann auf, wenn man sie am wenigsten gebrauchen kann.
1. Syntaxfehler: "Hab das IF nicht geschlossen"
Syntaxfehler sind die absoluten Basics, aber sie passieren öfter, als du denkst. Zum Beispiel, wenn du vergisst, einen IF-Block mit END IF; zu schließen, meckert der Compiler sofort.
Beispiel für einen Fehler:
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positiv';
ELSE
RETURN 'Negativ';
-- irgendwo fehlt END IF;
END;
$$ LANGUAGE plpgsql;
Wenn du diesen Code ausführst, bekommst du einen Fehler: ERROR: syntax error at or near "END". Warum? Weil der IF-Block offen geblieben ist.
Wie kann man solche Fehler vermeiden?
Immer eine klare Struktur im Code behalten. Wenn du einen Block öffnest (zum Beispiel IF), schreib direkt das Schließen dazu. Hier die korrigierte Version:
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positiv';
ELSE
RETURN 'Negativ';
END IF; -- vergiss nicht, den Block zu schließen
END;
$$ LANGUAGE plpgsql;
2. Vergessene Behandlung aller Fälle im CASE: "Was, wenn ich in keinen Fall passe?"
Wenn du CASE benutzt, solltest du immer einen ELSE-Zweig für unerwartete Werte einbauen. Fehlt der, kann das zu einem ungewollten NULL führen.
Beispiel für einen Fehler:
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Ausgezeichnet'
WHEN 'B' THEN 'Gut'
WHEN 'C' THEN 'Durchschnitt'
-- Was, wenn grade = 'D' oder eine andere Note?
END;
END;
$$ LANGUAGE plpgsql;
Wenn du den Wert D übergibst, gibt die Funktion NULL zurück – das kann später zu Problemen führen.
Korrigierte Version:
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Ausgezeichnet'
WHEN 'B' THEN 'Gut'
WHEN 'C' THEN 'Durchschnitt'
ELSE 'Unbekannte Note' -- Fängt alle anderen Fälle ab
END;
END;
$$ LANGUAGE plpgsql;
3. Probleme mit Endlosschleifen: "Warum hängt der Server?"
Wenn du eine LOOP-Schleife verwendest, vergisst du leicht, eine Abbruchbedingung einzubauen. Das führt zu einer Endlosschleife:
Beispiel für einen Fehler:
CREATE OR REPLACE FUNCTION infinite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
-- Keine Abbruchbedingung!
END LOOP;
END;
$$ LANGUAGE plpgsql;
Dieser Code lässt den Server hängen, weil die Schleife nie endet.
Wie beheben:
Füge eine Abbruchbedingung mit EXIT hinzu:
CREATE OR REPLACE FUNCTION finite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
IF i > 10 THEN
EXIT; -- Abbruchbedingung
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
4. Übersprungene Iterationen in Schleifen: "Was ist mit fehlenden Daten?"
Wenn du CONTINUE nutzt, um Iterationen zu überspringen, kann ein Fehler passieren, wenn du nicht alle Fälle beachtest. Zum Beispiel:
Beispiel für einen Fehler:
CREATE OR REPLACE FUNCTION skip_even()
RETURNS VOID AS $$
DECLARE
i INTEGER := 0;
BEGIN
WHILE i < 10 LOOP
i := i + 1;
IF i % 2 = 0 THEN
CONTINUE; -- Überspringt gerade Zahlen einfach
END IF;
RAISE NOTICE 'Ungerade Zahl: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Was, wenn alle Zahlen gerade sind? Der Server läuft zwar, aber du siehst kein Ergebnis.
Wie beheben:
Stell sicher, dass du alle Daten korrekt behandelst und füge Logging hinzu, um die Kontrolle zu behalten:
CREATE OR REPLACE FUNCTION skip_even_logging()
RETURNS VOID AS $$
DECLARE
i INTEGER := 0;
BEGIN
WHILE i < 10 LOOP
i := i + 1;
IF i % 2 = 0 THEN
RAISE NOTICE 'Überspringe gerade Zahl: %', i;
CONTINUE;
END IF;
RAISE NOTICE 'Ungerade Zahl: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Jetzt siehst du, welche Zahlen übersprungen wurden.
5. Falsche Fehlerbehandlung: "Wo ist mein RAISE EXCEPTION?"
Fehlerbehandlung mit RAISE EXCEPTION ist ein mächtiges Tool, aber kann durch falsche Nutzung schnell schiefgehen.
Beispiel für einen Fehler:
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE 'Negative Zahl ist nicht erlaubt!';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
Dieser Code wirft einen Fehler, weil der Syntax von RAISE falsch ist (es fehlt das Level).
Korrigierte Version:
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE EXCEPTION 'Negative Zahl ist nicht erlaubt!';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
6. Fehler beim Logging: "Warum werden meine Fehler nicht ins error_log geschrieben?"
Falsche Einträge in die error_log-Tabelle können durch Fehler in INSERT INTO-Statements passieren.
Beispiel für einen Fehler:
CREATE OR REPLACE FUNCTION log_error(err_msg TEXT)
RETURNS VOID AS $$
BEGIN
INSERT INTO error_log (error_message, error_time)
VALUES (err_msg, CURRENT_TIMESTAMP); -- Und wenn die Spaltennamen geändert wurden?
END;
$$ LANGUAGE plpgsql;
Wenn in der Tabelle error_log der Spaltenname geändert wurde (z.B. auf error_msg), gibt es einen Fehler.
Wie vermeiden:
Prüfe immer die Struktur der Tabelle oder nutze ein striktes Schema für deine Datenverwaltung.
7. Allgemeine Unachtsamkeit und "menschlicher Faktor"
Fehler sind nicht nur technisch, sondern oft auch einfach Unachtsamkeit. Vergessene Debug-Ausgaben, ungenutzte Variablen oder fehlendes Code-Formatting machen deine Funktion schnell zum Chaos.
Beispiel:
DECLARE
i INTEGER; -- Wozu, wenn die Variable nicht genutzt wird?
Lösung: Lösch unnötigen Code, damit alles sauber und verständlich bleibt.
Jetzt bist du bereit, die häufigsten Fehler in PL/pgSQL zu vermeiden und Code zu schreiben, der mehr Spaß als Frust bringt. Teste, logge und fixe Bugs rechtzeitig – das spart dir viele Nerven und Support-Anrufe!
GO TO FULL VERSION