Ein Trigger ist ein Programmteil, der automatisch ausgeführt wird, wenn bestimmte Datenbankoperationen (INSERT, UPDATE oder DELETE) auf einer Tabelle ausgeführt werden. Trigger können vor oder nach der Operation ausgelöst werden.
-- Grundlegende Trigger-Syntax
DELIMITER //
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON tabelle
FOR EACH ROW
BEGIN
-- Trigger-Code
END //
DELIMITER ;Anwendungsfälle für Trigger:
DELIMITER //
-- Lagerbestand bei neuer Bestellung aktualisieren
CREATE TRIGGER bestellung_nach_insert
AFTER INSERT ON bestellpositionen
FOR EACH ROW
BEGIN
-- Lagerbestand reduzieren
UPDATE produkte
SET lagerbestand = lagerbestand - NEW.menge
WHERE produkt_id = NEW.produkt_id;
-- Protokollierung
INSERT INTO log_tabelle
(zeitpunkt, aktion, tabelle, datensatz_id)
VALUES
(NOW(), 'INSERT', 'bestellpositionen', NEW.position_id);
END //
-- Prüfung vor dem Einfügen
CREATE TRIGGER bestellung_vor_insert
BEFORE INSERT ON bestellpositionen
FOR EACH ROW
BEGIN
DECLARE v_lagerbestand INT;
-- Aktuellen Lagerbestand ermitteln
SELECT lagerbestand
INTO v_lagerbestand
FROM produkte
WHERE produkt_id = NEW.produkt_id;
-- Prüfen ob genug auf Lager
IF v_lagerbestand < NEW.menge THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Nicht genügend Lagerbestand!';
END IF;
END //
DELIMITER ;DELIMITER //
-- Änderungen am Kundenrabatt protokollieren
CREATE TRIGGER kunde_vor_update
BEFORE UPDATE ON kunden
FOR EACH ROW
BEGIN
-- Wenn sich der Rabatt ändert
IF NEW.rabatt != OLD.rabatt THEN
-- Protokolleintrag erstellen
INSERT INTO rabatt_historie
(kunde_id, alter_rabatt, neuer_rabatt, aenderungsdatum)
VALUES
(OLD.kunde_id, OLD.rabatt, NEW.rabatt, NOW());
END IF;
END //
-- Automatische Statusaktualisierung
CREATE TRIGGER bestellung_nach_update
AFTER UPDATE ON bestellungen
FOR EACH ROW
BEGIN
-- Bei Änderung auf "versendet"
IF NEW.status = 'versendet' AND OLD.status != 'versendet' THEN
-- Versanddatum setzen
UPDATE bestellungen
SET versanddatum = CURRENT_DATE
WHERE bestell_id = NEW.bestell_id;
-- E-Mail-Benachrichtigung in Warteschlange
INSERT INTO mail_queue
(empfaenger_id, betreff, nachricht)
SELECT
k.kunde_id,
'Ihre Bestellung wurde versendet',
CONCAT('Bestellung ', NEW.bestellnummer, ' ist unterwegs')
FROM kunden k
WHERE k.kunde_id = NEW.kunde_id;
END IF;
END //
DELIMITER ;DELIMITER //
-- Archivierung vor dem Löschen
CREATE TRIGGER bestellung_vor_delete
BEFORE DELETE ON bestellungen
FOR EACH ROW
BEGIN
-- Bestellung archivieren
INSERT INTO bestellungen_archiv
SELECT *, NOW() as archiv_datum
FROM bestellungen
WHERE bestell_id = OLD.bestell_id;
-- Bestellpositionen archivieren
INSERT INTO bestellpositionen_archiv
SELECT *, NOW() as archiv_datum
FROM bestellpositionen
WHERE bestell_id = OLD.bestell_id;
-- Bestellpositionen löschen
DELETE FROM bestellpositionen
WHERE bestell_id = OLD.bestell_id;
END //
-- Lagerbestand nach Stornierung aktualisieren
CREATE TRIGGER bestellposition_nach_delete
AFTER DELETE ON bestellpositionen
FOR EACH ROW
BEGIN
-- Lagerbestand erhöhen
UPDATE produkte
SET lagerbestand = lagerbestand + OLD.menge
WHERE produkt_id = OLD.produkt_id;
-- Protokollierung
INSERT INTO log_tabelle
(zeitpunkt, aktion, tabelle, datensatz_id)
VALUES
(NOW(), 'DELETE', 'bestellpositionen', OLD.position_id);
END //
DELIMITER ;Praktische Tipps:
-- Komplexe Logik in Stored Procedure auslagern
DELIMITER //
CREATE PROCEDURE bestellung_verarbeiten(
IN p_bestell_id INT
)
BEGIN
-- Komplexe Verarbeitung
END //
CREATE TRIGGER bestellung_nach_insert
AFTER INSERT ON bestellungen
FOR EACH ROW
BEGIN
-- Nur Prozedur aufrufen
CALL bestellung_verarbeiten(NEW.bestell_id);
END //
DELIMITER ;-- Gefährlich: Gegenseitige Trigger
CREATE TRIGGER tabelle1_update
AFTER UPDATE ON tabelle1
FOR EACH ROW
UPDATE tabelle2 ...; -- Löst tabelle2_update aus
CREATE TRIGGER tabelle2_update
AFTER UPDATE ON tabelle2
FOR EACH ROW
UPDATE tabelle1 ...; -- Löst tabelle1_update ausDELIMITER //
CREATE TRIGGER sicherer_trigger
BEFORE INSERT ON wichtige_tabelle
FOR EACH ROW
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Fehler im Trigger';
END;
-- Trigger-Logik
END //
DELIMITER ;-- Kommentare für Trigger
DELIMITER //
CREATE TRIGGER bestellung_trigger
AFTER INSERT ON bestellungen
FOR EACH ROW
BEGIN
/* Trigger: bestellung_trigger
Zweck: Automatische Verarbeitung neuer Bestellungen
Erstellt von: Max Mustermann
Datum: 2024-01-15
Funktionsweise:
1. Lagerbestand aktualisieren
2. Protokolleintrag erstellen
3. E-Mail-Benachrichtigung senden */
-- Trigger-Logik
END //
DELIMITER ;