觸發器 是針對特定表的 INSERT、UPDATE、DELETE 事件,自動執行的預儲 SQL 程式碼。MySQL 5.0+ 引入,5.7/8.0 持續增強。典型用途:審計日誌、衍生欄位維護、跨表同步、資料完整性檢查。
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON table_name
FOR EACH ROW
BEGIN
-- SQL 陳述式;可使用 NEW.col / OLD.col 存取新舊值
END;
BEFORE:事件前執行,可修改 NEW 值AFTER:事件後執行,不可修改 NEWFOR EACH ROW:逐列觸發(MySQL 僅支援行級)CREATE TABLE `data` (`name` VARCHAR(255));
CREATE TABLE `chars` (`count` INT(10));
INSERT INTO `chars` VALUES (0);
CREATE TRIGGER `t1` AFTER INSERT ON `data`
FOR EACH ROW
UPDATE `chars` SET `count` = `count` + CHAR_LENGTH(NEW.`name`);
-- 測試
INSERT INTO `data` VALUES ('Alice'), ('Bob');
SELECT * FROM `chars`; -- count = 8
CREATE TABLE `accounts` (
`id` INT PRIMARY KEY,
`label` VARCHAR(50),
`balance` DECIMAL(12,2)
);
INSERT INTO `accounts` VALUES
(1,'Savings #1',500),
(2,'Current #1',2000),
(3,'Current #2',3500);
CREATE TABLE `audit` (
`id` INT,
`balance` DECIMAL(12,2),
`user` VARCHAR(100),
`time` DATETIME
);
CREATE TRIGGER `audit_balance` AFTER UPDATE ON `accounts`
FOR EACH ROW
INSERT INTO `audit` (`id`,`balance`,`user`,`time`)
VALUES (OLD.`id`, NEW.`balance`, CURRENT_USER(), NOW());
-- 測試
UPDATE `accounts` SET `balance`=500 WHERE `id`=1;
UPDATE `accounts` SET `balance`=900 WHERE `id`=3;
SELECT * FROM `audit`;
/* 結果:
id=1, balance=500, user=root@localhost, time=...
id=3, balance=900, user=root@localhost, time=...
*/
SHOW TRIGGERS\G 或 SELECT * FROM information_schema.TRIGGERSDROP TRIGGER [IF EXISTS] trigger_nameTRIGGER 權限(MySQL 5.1.6+)BEFORE 修改 NEW:可能繞過應用層驗證邏輯SET @TRIGGER_DISABLED=1; 配合觸發器內判斷跳過mysqldump --triggers 預設包含,還原時需確保目標版本相容觸發器將業務規則下沉至資料庫層,能保證跨應用的一致性(如審計日誌)。但業務邏輯盡量留在應用層,觸發器僅用於無法繞過的資料完整性與審計場景,並建立完善的單元測試與文檔。