觸發器是綁定在表上的特殊存儲程序,當 INSERT/UPDATE/DELETE 發生時自動執行,具備自動性與事務一致性。本文從四要素、語法、實戰同步雙表、刪除/修改觸發器、優缺點分析五個維度完整講解。
BEGIN ... END 包裹)CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
FOR EACH ROW
BEGIN
-- SQL statements
END;
CREATE TABLE g (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), num INT);
CREATE TABLE o (oid INT PRIMARY KEY AUTO_INCREMENT, gid INT, much INT);
INSERT INTO g(name,num) VALUES ('商品1',10),('商品2',10),('商品3',10);
DELIMITER $$ CREATE TRIGGER tg_after_insert AFTER INSERT ON o FOR EACH ROW BEGIN UPDATE g SET num = num - NEW.much WHERE id = NEW.gid; END$$ DELIMITER ;
DELIMITER $$ CREATE TRIGGER tg_after_delete AFTER DELETE ON o FOR EACH ROW BEGIN UPDATE g SET num = num + OLD.much WHERE id = OLD.gid; END$$ DELIMITER ;
DELIMITER $$ CREATE TRIGGER tg_after_update AFTER UPDATE ON o FOR EACH ROW BEGIN UPDATE g SET num = num + OLD.much - NEW.much WHERE id = OLD.gid; END$$ DELIMITER ;
| 事件 | NEW | OLD |
|---|---|---|
| INSERT | 新行所有欄位 | 不可用 |
| UPDATE | 修改後的值 | 修改前的值 |
| DELETE | 不可用 | 被刪除行的值 |
-- INSERT 同步
CREATE TRIGGER tr_a_insert AFTER INSERT ON t_a FOR EACH ROW
BEGIN
INSERT INTO t_b (username, groupid) VALUES (NEW.username, NEW.groupid);
END;
-- UPDATE 同步(僅關鍵欄位變更時)
CREATE TRIGGER tr_a_update AFTER UPDATE ON t_a FOR EACH ROW
BEGIN
IF NEW.groupid != OLD.groupid OR NEW.username != OLD.username THEN
UPDATE t_b SET groupid=NEW.groupid, username=NEW.username
WHERE username=OLD.username AND groupid=OLD.groupid;
END IF;
END;
-- DELETE 同步
CREATE TRIGGER tr_a_delete AFTER DELETE ON t_a FOR EACH ROW
BEGIN
DELETE FROM t_b WHERE username=OLD.username AND groupid=OLD.groupid;
END;
| 優點 | 缺點 |
|---|---|
| 業務邏輯集中、自動執行 | 除錯困難,無單步調試、斷點 |
| 保證事務一致性 | 隱性邏輯導致維護成本高 |
| 減少應用層往返 | 遷移資料庫時易遺漏 |
| 可實現跨表級聯操作 | 大量觸發器影響寫入效能 |
tg_{table}_{event}_{timing},如 tg_order_after_insert。善用觸發器能簡化應用碼,但請謹記「顯式優於隱式」,關鍵路徑盡量保持在應用層可見可控。