PostgreSQL-Trigger auf Zeilenebene
Trigger in PostgreSQL sind Prozeduren, die als Reaktion auf bestimmte Ereignisse in einer bestimmten Tabelle oder Ansicht automatisch ausgeführt werden. Trigger auf Zeilenebene werden speziell für jede Zeile ausgeführt, die von einem Ereignis wie `INSERT`, `UPDATE` oder `DELETE` betroffen ist.
Verwendung
Trigger auf Zeilenebene werden verwendet, um Geschäftsregeln durchzusetzen, Daten zu validieren oder eine benutzerdefinierte Protokollierung auf Zeilenebene durchzuführen. Sie sind so definiert, dass sie bestimmte Aktionen ausführen, wenn eine Zeile auf eine bestimmte Weise geändert wird.
sql
CREATE TRIGGER trigger_name
AFTER | BEFORE INSERT | UPDATE | DELETE
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();
In dieser Syntax gibt `FOR EACH ROW` an, dass der Trigger für jede betroffene Zeile ausgelöst wird, und `EXECUTE FUNCTION` ruft die Funktion auf, die die auszuführende Logik enthält.
Beispiele
1. Basic Insert Trigger
sql
CREATE OR REPLACE FUNCTION log_new_inserts()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation, timestamp)
VALUES (TG_TABLE_NAME, 'INSERT', now());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_insert
AFTER INSERT ON employees
FOR EACH ROW
EXECUTE FUNCTION log_new_inserts();
In diesem Beispiel wird ein Trigger erstellt, der jede neue `INSERT`-Operation in der Tabelle `Mitarbeiter` in einer `audit_log`-Tabelle protokolliert.
2. Auslöser mit Bedingung aktualisieren
sql
CREATE OR REPLACE 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 salary_check
BEFORE UPDATE ON employees
FOR EACH ROW
EXECUTE FUNCTION check_salary_update();
Hier verhindert ein Auslöser Gehaltskürzungen, indem er eine Ausnahme auslöst, wenn das neue Gehalt während eines `UPDATE` niedriger ist als das alte.
3. Auslöser mit Protokollierung löschen
sql
CREATE OR REPLACE FUNCTION log_delete()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO delete_log (table_name, deleted_row_id, timestamp)
VALUES (TG_TABLE_NAME, OLD.id, now());
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_delete
AFTER DELETE ON orders
FOR EACH ROW
EXECUTE FUNCTION log_delete();
In diesem Beispiel werden die Details der gelöschten Zeilen aus der Tabelle "Bestellungen" zu Prüfzwecken in einem "delete_log" protokolliert. Er geht davon aus, dass `OLD.id` dem Primärschlüssel oder einem eindeutigen Bezeichner der Zeile entspricht.
Tipps und bewährte Praktiken
- Setze die Auslöser mit Bedacht ein. Die übermäßige Verwendung von Triggern kann zu komplexen und schwer zu debuggenden Systemen führen.
- Achte auf Atomarität. Die Triggerfunktion sollte atomar und idempotent sein, um die Datenintegrität zu wahren.
- Berücksichtige die Auswirkungen auf die Leistung. Trigger verursachen zusätzlichen Overhead und werden synchron mit der auslösenden Operation ausgeführt; stelle sicher, dass sie für die Leistung optimiert sind, damit sie die Datenbankoperationen nicht verlangsamen.
- Teste die Auslöser gründlich. Sorge für umfassende Tests, um sicherzustellen, dass sich die Auslöser in allen Szenarien korrekt verhalten.
- Dokumentiere die Auslöselogik. Dokumentiere den Zweck und die Logik jedes Auslösers klar und deutlich, damit du ihn später nachschlagen und pflegen kannst.
Zusätzliche Informationen
Besondere Variablen: PostgreSQL-Trigger verwenden spezielle Variablen wie `TG_TABLE_NAME`, `NEW` und `OLD`, um Kontext bereitzustellen. TG_TABLE_NAME" bezieht sich auf den Namen der Tabelle, mit der der Trigger verknüpft ist, "NEW" enthält die neuen Zeilendaten für "INSERT"- oder "UPDATE"-Operationen und "OLD" enthält die vorhandenen Zeilendaten für "UPDATE"- oder "DELETE"-Operationen.