Trigger — spezielle Datenbankobjekte, die die Ausführung eines bestimmten Codes automatisch auslösen (normalerweise in SQL oder in prozeduralen Erweiterungssprachen, z.B. PL/pgSQL für PostgreSQL), wenn ein Ereignis eintritt: INSERT, UPDATE oder DELETE in einer Tabelle.
Vorteile:
Nachteile:
Wann anwenden:
Beispiel für einen Trigger (PostgreSQL):
CREATE TABLE employee_audit ( id SERIAL PRIMARY KEY, employee_id INT, old_salary NUMERIC, new_salary NUMERIC, changed_at TIMESTAMP ); CREATE OR REPLACE FUNCTION audit_salary() RETURNS TRIGGER AS $$ BEGIN IF NEW.salary <> OLD.salary THEN INSERT INTO employee_audit(employee_id, old_salary, new_salary, changed_at) VALUES (OLD.id, OLD.salary, NEW.salary, NOW()); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_salary_update AFTER UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION audit_salary();
Kann man innerhalb eines Triggers dieselbe Tabelle aktualisieren, auf die er gesetzt ist? Was wird passieren?
Antwort:
Wenn der Trigger auf ein Ereignis eingestellt ist, sagen wir mal UPDATE der Tabelle, und innerhalb von sich selbst ein weiteres UPDATE dieser Tabelle ausführt, führt dies zu einer unendlichen Rekursion (Endlosschleife) und zum Absturz des Befehls oder zu einem Fehler wegen der Überschreitung der Trigger-Tiefe. Daher sollte man immer darauf achten, dass keine Rekursion entsteht, oder Optionen verwenden, die rekursive Aufrufe erlauben/verhindern.
Beispiel:
-- Mit dieser Konstruktion kann der Trigger wiederholt werden: CREATE OR REPLACE FUNCTION recursive_update() RETURNS TRIGGER AS $$ BEGIN UPDATE employees SET salary = salary * 1.01 WHERE id = NEW.id; -- wird erneut ausgeführt RETURN NEW; END; $$ LANGUAGE plpgsql;
Geschichte
In der Buchhaltungs-CRM wurde ein Trigger implementiert, um die Operationen bei Änderungen in der Transaktionstabelle automatisch im Log zu protokollieren. Unter hoher Last arbeitete der Dienst langsamer, und die Analyse zeigte: Der Trigger benötigt viel Zeit, um in das Log zu schreiben und wurde nicht optimiert (z.B. schrieb er nur bedeutende Ereignisse).
Geschichte
Im Projekt für das Inventarmanagement wurde ein BEFORE INSERT-Trigger zur Berechnung der Positions-ID verwendet. Eine fehlerhafte Logik der ID führte zu Doppelungen von Daten, weshalb der Fehler lange unentdeckt blieb, da er "im Hintergrund" arbeitete.
Geschichte
In der HR-Plattform führte der Trigger bei jedem INSERT zu Massenupdates von Einträgen in den Eltern- und Kindtabellen. Aufgrund von Fehlern in der Logik des Triggers trat eine Rekursion auf, die alle Operationen mit den Tabellen vollständig blockierte. Der Trigger musste deaktiviert werden, und es war eine komplizierte Rollback-Migration erforderlich, um die Tabellen zu entsperren.