PostgreSQL Einführung in Triggers
Trigger in PostgreSQL sind spezielle Prozeduren, die automatisch ausgeführt oder ausgelöst werden, wenn bestimmte Ereignisse in einer Datenbanktabelle auftreten. Sie werden eingesetzt, um die Integrität der Daten zu wahren, Geschäftsregeln durchzusetzen und komplexe Prüfungen oder Transformationen zu automatisieren.
Verwendung
Trigger werden eingesetzt, um automatisch auf Ereignisse wie `INSERT`-, `UPDATE`- oder `DELETE`-Operationen in einer Tabelle zu reagieren. Sie können so eingestellt werden, dass sie `VOR`, `NACH` oder `NACH` dem Ereignis ausgeführt werden und können optional davon abhängig gemacht werden, ob das Ereignis erfolgreich ist. Trigger können auf Zeilenebene definiert werden, d.h. sie werden für jede betroffene Zeile ausgeführt, oder auf Anweisungsebene, d.h. sie werden einmal pro SQL-Anweisung ausgeführt.
CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF }
{ INSERT | UPDATE | DELETE }
ON table_name
FOR EACH { ROW | STATEMENT }
EXECUTE FUNCTION function_name();
In dieser Syntax definiert `CREATE TRIGGER` einen neuen Trigger mit dem Namen `trigger_name`, der eine bestimmte Funktion `function_name` entweder vor, nach oder anstelle eines datenverändernden Ereignisses auf `table_name` aufruft.
Trigger interagieren mit Transaktionssteuerungsbefehlen wie `COMMIT` und `ROLLBACK`. Wenn ein Trigger einen Fehler verursacht, wird in der Regel die gesamte Transaktion zurückgerollt, es sei denn, sie wird explizit behandelt.
Beispiele
1. Grundlegender Auslöser für Auditing
CREATE TABLE audit_log (
id SERIAL PRIMARY KEY,
operation VARCHAR(10),
operation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE OR REPLACE FUNCTION log_insert() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log(operation) VALUES ('INSERT');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER insert_audit
AFTER INSERT ON target_table
FOR EACH ROW
EXECUTE FUNCTION log_insert();
Dieses einfache Beispiel protokolliert jede `INSERT`-Operation auf `target_table` in der Tabelle `audit_log`.
2. Auslösen mit bedingter Logik
CREATE OR REPLACE FUNCTION check_salary() 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 salary_check
BEFORE UPDATE ON employees
FOR EACH ROW
EXECUTE FUNCTION check_salary();
Dieser Auslöser stellt sicher, dass das Gehalt eines Mitarbeiters während eines Aktualisierungsvorgangs nicht verringert werden kann.
3. Kaskadenauslöser
CREATE OR REPLACE FUNCTION delete_cascade() RETURNS TRIGGER AS $$
BEGIN
DELETE FROM orders WHERE customer_id = OLD.id;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER cascade_delete
AFTER DELETE ON customers
FOR EACH ROW
EXECUTE FUNCTION delete_cascade();
In diesem Beispiel werden alle mit einem Kunden verbundenen Bestellungen automatisch gelöscht, wenn der Kunde entfernt wird.
Auslöser verwalten
Um einen Trigger zu deaktivieren oder fallen zu lassen, wenn er nicht mehr benötigt wird, kannst du die folgenden Befehle verwenden:
ALTER TABLE table_name DISABLE TRIGGER trigger_name;
DROP TRIGGER trigger_name ON table_name;
Um vorhandene Trigger in einer Datenbank zu sehen, kannst du den Systemkatalog `pg_trigger` abfragen.
Tipps und bewährte Praktiken
- Halte die Auslöser einfach. Komplexe Logik kann zu Leistungsengpässen und Wartungsproblemen führen.
- Teste gründlich. Stelle sicher, dass deine Auslöser wie erwartet funktionieren, indem du sie in verschiedenen Szenarien testest.
- Dokumentauslöser. Dokumentiere klar den Zweck und die Funktionsweise jedes Triggers, um zukünftigen Entwicklern zu helfen.
- Berücksichtige Erlaubnisse. Stelle sicher, dass die Benutzer, die die Ereignisse auslösen, die entsprechenden Berechtigungen haben, um die zugehörigen Funktionen auszuführen.
- Überwache die Auswirkungen auf die Leistung. Sei dir darüber im Klaren, dass die umfangreiche Verwendung von Triggern die Leistung beeinträchtigen kann, insbesondere bei Tabellen mit vielen Transaktionen.
- Vermeide rekursive Auslöser. Rekursive Auslöser können zu Endlosschleifen führen und sollten mit Vorsicht behandelt werden.