PostgreSQL CREATE TRIGGER
Trigger in PostgreSQL sind Datenbank-Callback-Funktionen, die automatisch ausgeführt oder ausgelöst werden, wenn ein bestimmtes Datenbankereignis eintritt, wie z.B. eine `INSERT`-, `UPDATE`-, `DELETE`- oder sogar `TRUNCATE`-Operation. Sie werden verwendet, um Geschäftsregeln durchzusetzen, Daten zu validieren und die Datenintegrität innerhalb der Datenbank zu wahren.
Verwendung
Trigger werden verwendet, um Aufgaben zu automatisieren, die beim Eintreten bestimmter Datenbankereignisse ausgeführt werden sollen, sodass weniger manuelle Eingriffe oder anwendungsseitige Logik erforderlich sind. Sie werden mit der Anweisung `CREATE TRIGGER` definiert, die das Ereignis und die zu ergreifende Aktion angibt.
sql
CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF }
{ INSERT | UPDATE | DELETE | TRUNCATE }
ON table_name
[ FOR EACH ROW | FOR EACH STATEMENT ]
EXECUTE PROCEDURE function_name();
In dieser Syntax definiert `CREATE TRIGGER` einen neuen Trigger mit dem Namen `Triggername`, der eine angegebene Funktion (`Funktionsname`) entweder vor, nach oder anstelle des angegebenen Ereignisses auf `Tabelle_name` ausführt. Die Klausel "FÜR JEDE ZEILE" gibt an, dass der Trigger einmal für jede vom Ereignis betroffene Zeile ausgeführt wird, während "FÜR JEDES STATEMENT" einmal pro auslösender Anweisung ausgeführt wird, unabhängig davon, wie viele Zeilen betroffen sind.
Beispiele
1. Basic Insert Trigger
sql
CREATE FUNCTION log_insert() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation) VALUES ('employees', 'INSERT');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_employee_inserts
AFTER INSERT ON employees
FOR EACH ROW EXECUTE PROCEDURE log_insert();
In diesem Beispiel wird ein Trigger erstellt, der jede Einfügeoperation in der Tabelle "Mitarbeiter" in einer Tabelle "audit_log" protokolliert.
2. Auslöser mit Bedingung aktualisieren
sql
CREATE FUNCTION check_salary_update() RETURNS TRIGGER AS $$
BEGIN
IF NEW.salary < OLD.salary THEN
RAISE EXCEPTION 'Salary cannot be decreased';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER prevent_salary_decrease
BEFORE UPDATE ON employees
FOR EACH ROW EXECUTE PROCEDURE check_salary_update();
Dieser Auslöser verhindert, dass die Gehälter der Beschäftigten sinken und stellt sicher, dass die Gehaltsaktualisierungen nur steigen oder gleich bleiben können. Hier stehen "NEU" und "ALT" für den neuen bzw. alten Zustand der Zeile, die bearbeitet wird.
3. Auslöser für Kaskadenlöschung
sql
CREATE FUNCTION delete_related_records() RETURNS TRIGGER AS $$
BEGIN
DELETE FROM orders WHERE customer_id = OLD.customer_id;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER cascade_delete_orders
AFTER DELETE ON customers
FOR EACH ROW EXECUTE PROCEDURE delete_related_records();
In diesem Beispiel wird ein Trigger eingerichtet, der automatisch alle mit einem Kunden verbundenen Bestellungen löscht, wenn dieser Kunde gelöscht wird.
4. INSTEAD OF Trigger Beispiel
INSTEAD OF-Trigger werden in der Regel mit Ansichten verwendet, um Aktionen anstelle der Standardoperation durchzuführen.
sql
CREATE FUNCTION log_view_update() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation) VALUES ('view_name', 'UPDATE');
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_view_updates
INSTEAD OF UPDATE ON my_view
FOR EACH ROW EXECUTE PROCEDURE log_view_update();
Dieser Trigger protokolliert Versuche, eine Ansicht zu aktualisieren, anstatt die Aktualisierung durchzuführen.
Tipps und bewährte Praktiken
- Lege die Auslösebedingungen klar fest. Stelle sicher, dass die Bedingungen, unter denen Auslöser ausgelöst werden, genau definiert sind, um unerwartetes Verhalten zu vermeiden.
- Verwende Auslöser sparsam. Die übermäßige Verwendung von Triggern kann zu komplexen Abhängigkeiten führen und die Fehlersuche erschweren.
- Dokumentiere die Auslöser gründlich. Dokumentiere klar und deutlich, was die einzelnen Auslöser bewirken und warum sie verwendet werden, damit du sie später nachschlagen kannst.
- Teste gründlich. Teste die Trigger immer in einer Entwicklungsumgebung, um sicherzustellen, dass sie wie vorgesehen und ohne Leistungseinbußen funktionieren.
- Berücksichtige die Auswirkungen auf die Leistung. Komplexe Trigger können sich auf die Leistung auswirken; überprüfe und optimiere sie, wenn nötig.
- Verhindern Sie rekursive Aufrufe. Verwende Befehle wie `ALTER TABLE ... ENABLE TRIGGER ...`, um die Aktivierung des Triggers zu kontrollieren und mögliche rekursive Aufrufschleifen zu verhindern.