PERFORM in der PostgreSQL-Welt ist so ein knallharter, schweigsamer Held, der auftaucht, seinen Job macht und wieder verschwindet, ohne irgendwelche Spuren in Form von Rückgabedaten zu hinterlassen. Dieser Befehl wird verwendet, wenn du einen SQL-Query innerhalb einer PL/pgSQL-Funktion ausführen willst, aber das Ergebnis nicht verarbeiten oder speichern musst. Die Hauptaufgabe von PERFORM ist es, einen Query auszuführen, damit etwas passiert – zum Beispiel Daten ändern oder eine andere Funktion aufrufen – aber nicht, um ein Ergebnis zu bekommen.
PERFORM wird immer dann genutzt, wenn uns das Ergebnis des Queries egal ist. Im Gegensatz zu einem normalen SELECT, der erwartet, dass du irgendwas mit dem Ergebnis machst, startet PERFORM einfach den Query und läuft still weiter. Das ist besonders praktisch, wenn du eine Funktion nur wegen ihrer Wirkung aufrufst, nicht wegen dessen, was sie zurückgibt. Zum Beispiel, um etwas ins Log zu schreiben. So wird dein Code einfacher und verständlicher: weniger unnötiges Zeug, mehr Klarheit.
Beispiele für die Nutzung von PERFORM
Funktionsaufrufe
Lass uns das mal an einem echten Beispiel anschauen. Stell dir vor, wir haben eine Funktion log_action, die Infos über User-Aktionen ins Log schreibt. Diese Funktion gibt nichts zurück, und wir wollen einfach nur, dass sie ausgeführt wird. So geht das mit PERFORM:
CREATE OR REPLACE FUNCTION log_action(user_id INT, action TEXT) RETURNS VOID AS $$
BEGIN
INSERT INTO logs (user_id, action, log_time)
VALUES (user_id, action, NOW());
END;
$$ LANGUAGE plpgsql;
-- Danach nutzen wir PERFORM, um diese Funktion aufzurufen:
PERFORM log_action(5, 'Benutzer hat sich eingeloggt');
Was passiert hier? Der Befehl PERFORM ruft die Funktion log_action auf, die einen Eintrag in die Tabelle logs schreibt. Wichtig: Das Ergebnis des Funktionsaufrufs wird ignoriert. Wir nutzen sie nur wegen ihres Effekts, nicht wegen Rückgabewerten.
Daten aktualisieren
Manchmal ist PERFORM praktisch, wenn du einen Query ausführen willst, um Daten zu ändern, aber das Ergebnis nicht brauchst. Zum Beispiel, um den Status einer Bestellung in der Tabelle orders zu aktualisieren.
CREATE OR REPLACE FUNCTION update_order_status(order_id INT, new_status TEXT) RETURNS VOID AS $$
BEGIN
UPDATE orders
SET status = new_status
WHERE id = order_id;
END;
$$ LANGUAGE plpgsql;
-- Wir nutzen PERFORM, um diese Funktion aufzurufen:
PERFORM update_order_status(101, 'Versendet');
Hier aktualisiert update_order_status den Status der Bestellung mit der ID 101. Uns interessiert das Ergebnis des SQL-Queries in der Funktion nicht, also ist PERFORM die perfekte Wahl.
Hilfsoperationen ausführen
Manchmal enthalten Funktionen Mini-Operationen, die sozusagen "Hilfslogik" sind und helfen, einen komplexen Prozess abzuschließen. Angenommen, wir wollen nach dem Update einer Tabelle den Cache leeren:
CREATE OR REPLACE FUNCTION clear_cache() RETURNS VOID AS $$
BEGIN
DELETE FROM cache_table;
END;
$$ LANGUAGE plpgsql;
-- Wir rufen sie in einer anderen Funktion auf:
CREATE OR REPLACE FUNCTION update_product(product_id INT, new_price NUMERIC) RETURNS VOID AS $$
BEGIN
UPDATE products
SET price = new_price
WHERE id = product_id;
-- Cache nach Datenänderung leeren:
PERFORM clear_cache();
END;
$$ LANGUAGE plpgsql;
Hier ist die Magie: Du kannst Aktionen nacheinander ausführen, indem du PERFORM nutzt, um Funktionen aufzurufen, deren Ergebnis dich überhaupt nicht interessiert.
Praktische Aufgaben
Lass uns ein paar Beispiele anschauen, wie PERFORM das Leben von Entwicklern leichter machen kann.
Beispiel 1: Logging der einzelnen Schritte einer Prozedur
Angenommen, wir haben eine komplexe Prozedur zur Zahlungsabwicklung und müssen jeden Schritt davon ins Log schreiben. Wir können eine Funktion log_stage definieren, um Infos zu speichern, und dann PERFORM nutzen:
CREATE OR REPLACE FUNCTION log_stage(stage_name TEXT) RETURNS VOID AS $$
BEGIN
INSERT INTO process_logs(stage, log_time)
VALUES (stage_name, NOW());
END;
$$ LANGUAGE plpgsql;
-- Und hier ein Beispiel für eine Prozedur:
CREATE OR REPLACE FUNCTION process_payment(payment_id INT) RETURNS VOID AS $$
BEGIN
-- Logging des Starts
PERFORM log_stage('Start der Zahlungsabwicklung');
-- Erster Schritt
UPDATE payments
SET status = 'In Bearbeitung'
WHERE id = payment_id;
PERFORM log_stage('Zahlungsstatus aktualisiert');
-- Letzter Schritt
UPDATE payments
SET status = 'Abgeschlossen'
WHERE id = payment_id;
PERFORM log_stage('Zahlung abgeschlossen');
END;
$$ LANGUAGE plpgsql;
Hier wird log_stage per PERFORM aufgerufen, um den Status bei jedem Schritt der Prozedur zu speichern. Das macht den Code leichter zu debuggen.
Beispiel 2: Benachrichtigungen auslösen
Stell dir vor, du hast ein Benachrichtigungssystem und musst nach jeder wichtigen Aktion eine Notification verschicken. PERFORM kann genutzt werden, um die dafür zuständige Funktion aufzurufen:
CREATE OR REPLACE FUNCTION send_notification(user_id INT, message TEXT) RETURNS VOID AS $$
BEGIN
INSERT INTO notifications (user_id, message, created_at)
VALUES (user_id, message, NOW());
END;
$$ LANGUAGE plpgsql;
-- Nutzung in einer Prozedur:
CREATE OR REPLACE FUNCTION complete_task(task_id INT) RETURNS VOID AS $$
DECLARE
user_id INT;
BEGIN
-- Autor der Aufgabe holen
SELECT assigned_to INTO user_id
FROM tasks
WHERE id = task_id;
-- Aufgabe abschließen
UPDATE tasks
SET status = 'Abgeschlossen'
WHERE id = task_id;
-- Benachrichtigung senden
PERFORM send_notification(user_id, 'Deine Aufgabe wurde abgeschlossen');
END;
$$ LANGUAGE plpgsql;
Hier sorgt PERFORM dafür, dass wir uns nur auf den Nebeneffekt – das Senden der Benachrichtigung – konzentrieren, und das Ergebnis der Funktion ignorieren.
Nützliche Tipps und typische Fehler
Wenn du PERFORM nutzt, solltest du ein paar Dinge beachten. Zum Beispiel: PERFORM prüft nicht, ob der Query Daten zurückgegeben hat. Das heißt, wenn das Ergebnis einer Funktion oder eines SQL-Queries wichtig für die Logik ist, solltest du besser SELECT INTO verwenden. Hier ein Beispiel:
-- Potenzieller Fehler
PERFORM some_function_that_must_return_value();
-- Korrektur
SELECT some_function_that_must_return_value() INTO some_variable;
Ein weiterer häufiger Fehler ist, PERFORM zu nutzen, wo du eigentlich das Ergebnis des Queries brauchst, zum Beispiel bei der Datenvalidierung. In solchen Fällen solltest du natürlich das Ergebnis holen und prüfen.
In echten Projekten hilft dir PERFORM, Funktionen und Prozeduren einfacher, lesbarer und leichter zu debuggen zu machen. Zusammen mit Logging (RAISE NOTICE) und den eingebauten Diagnosefunktionen von PostgreSQL wie current_query() wird es zu einem wichtigen Tool, um robuste, kontrollierbare und verständliche Systeme zu bauen.
GO TO FULL VERSION