Hi,
Ein potenziell verwirrendes Beispiel dafür ist die Syntax von INSERT INTO ... ON DUPLICATE KEY UPDATE ...: Für jede Zeile wird ein BEFORE INSERT-Trigger aktiviert, gefolgt entweder von einem AFTER INSERT-Trigger oder von dem Triggerpaar aus BEFORE UPDATE und AFTER UPDATE, je nachdem, ob ein doppelter Schlüssel für die Zeile vorlag oder nicht."
Wenn Insert getriggert werden soll: Trigger ... After Insert
Wenn Update getriggert werden soll: Trigger ... Before Update
Das ist nicht vollständig, und das sagt der Text auch aus. Schau dir mal das Ergebnis hier an:
DROP TABLE IF EXISTS testtable;
CREATE TABLE testtable
(
id INTEGER AUTO_INCREMENT,
ival INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);
DROP TABLE IF EXISTS testtable_log;
CREATE TABLE testtable_log
(
id INTEGER AUTO_INCREMENT,
ival INTEGER NOT NULL DEFAULT 0,
trigger_name VARCHAR(20),
PRIMARY KEY(id)
);
DELIMITER |
CREATE TRIGGER BeforeInsertTestTable BEFORE INSERT ON testtable FOR EACH ROW
INSERT INTO testtable_log (ival, trigger_name) VALUES (NEW.ival, 'BEFORE INSERT'); |
CREATE TRIGGER AfterInsertTestTable AFTER INSERT ON testtable FOR EACH ROW
INSERT INTO testtable_log (ival, trigger_name) VALUES (NEW.ival, 'AFTER INSERT'); |
CREATE TRIGGER BeforeUpdateTestTable BEFORE UPDATE ON testtable FOR EACH ROW
INSERT INTO testtable_log (ival, trigger_name) VALUES (NEW.ival, 'BEFORE UPDATE'); |
CREATE TRIGGER AfterUpdateTestTable AFTER UPDATE ON testtable FOR EACH ROW
INSERT INTO testtable_log (ival, trigger_name) VALUES (NEW.ival, 'AFTER UPDATE'); |
DELIMITER ;
INSERT INTO testtable (id, ival) VALUES (1, 1) ON DUPLICATE KEY UPDATE ival = ival+1;
INSERT INTO testtable (id, ival) VALUES (1, 1) ON DUPLICATE KEY UPDATE ival = ival+1;
SELECT * FROM testtable_log;
Das Ergebnis ist
id, ival, trigger_name
1, 1, BEFORE INSERT
2, 1, AFTER INSERT
3, 1, BEFORE INSERT
4, 2, BEFORE UPDATE
5, 2, AFTER UPDATE
Zeilen 1 und 2 kommen vom ersten INSERT-Statement, Zeilen 3, 4 und 5 vom zweiten.
Beachte, dass NEW.* beim BEFORE-INSERT-Trigger noch den Wert enthält, der im INSERT-Statement angegeben wurde. Dann wurde festgestellt, dass der Primary-Key-Constraint greift und das Trigger-Paar BEFORE/UPDATE-Trigger wird aufgerufen, diesmal mit den aktualisierten Wert.
Bis die Tage,
Matti