Matti Mäkitalo: Trigger mySQL, Verständnisfrage

Beitrag lesen

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