觸發器是響應表 DML 事件(INSERT/UPDATE/DELETE)自動執行的特殊存儲過程,提供比約束更精細的數據控制能力。本文從零開始,系統講解觸發器概念、語法、NEW/OLD 使用、實戰測試、管理命令,適合初學者快速上手。
| 作用領域 | 典型場景 |
|---|---|
| 安全性 | 基於時間/數據值限制操作(如非工作時間禁止修改、股價漲幅≤10%) |
| 審計 | 記錄用戶操作語句、變更前後值寫入審計表 |
| 數據完整性 | 複雜檢查(非標準約束)、跨表級聯更新/刪除/置 NULL/置默認值 |
| 關聯完整性 | 外鍵不匹配時回滾、父表刪除時級聯處理子表 |
| 數據同步 | 實時複製表數據到備份表/異構系統 |
| 自動計算 | 衍生列自動計算、閾值觸發告警(如帳戶餘額<5萬發警告) |
CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name
trigger_time trigger_event ON tbl_name
FOR EACH ROW trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_name表名_事件縮寫_時機,如 ttlsa_users_ai(after insert),長度 ≤ 64 字符DEFINERtrigger_timeBEFORE:行寫入前(可修改 NEW);AFTER:行寫入後(不可修改 NEW)trigger_eventINSERT(含 LOAD DATA/REPLACE)、UPDATE、DELETE(含 REPLACE);不觸發:DROP TABLE、TRUNCATE TABLE、分區刪除FOR EACH ROWtrigger_bodyBEGIN ... END;支援流控、變量、異常處理;受函數限制(不可返回結果集、不可動態 SQL 等)| 事件 | NEW | OLD | 說明 |
|---|---|---|---|
| INSERT | ✅ 可讀寫(BEFORE) | ❌ 报错 | 無舊行 |
| UPDATE | ✅ 可讀寫(BEFORE) | ✅ 僅讀 | 新/舊值對比 |
| DELETE | ❌ 报错 | ✅ 僅讀 | 無新行 |
錯誤示例:ERROR 1363 (HY000): There is no OLD row in on INSERT trigger
CREATE TABLE ttlsa_users ( uid INT(11) UNSIGNED PRIMARY KEY, username VARCHAR(40) NOT NULL, password VARCHAR(40) NOT NULL, createtime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); CREATE TABLE ttlsa_users3 ( uid INT(11) UNSIGNED, userinfo VARCHAR(200) );
DELIMITER // CREATE TRIGGER ttlsa_users_ai AFTER INSERT ON ttlsa_users FOR EACH ROW INSERT INTO ttlsa_users3 (uid, userinfo) VALUES (NEW.uid, JSON_OBJECT(NEW.uid, NEW.username, NEW.password)); // CREATE TRIGGER ttlsa_users_au AFTER UPDATE ON ttlsa_users FOR EACH ROW UPDATE ttlsa_users3 SET userinfo = JSON_OBJECT(NEW.uid, NEW.username, NEW.password) WHERE uid = OLD.uid; // DELIMITER ;
INSERT INTO ttlsa_users VALUES (890, 'xuhh', MD5('abc'));
SELECT * FROM ttlsa_users3;
-- {"uid":890,"username":"xuhh","password":"900150983cd24fb0d6963f7d28e17f72"}
UPDATE ttlsa_users SET password = 'test_update' WHERE uid = 890;
SELECT * FROM ttlsa_users3;
-- {"uid":890,"username":"xuhh","password":"test_update"}
-- 列出所有觸發器 SHOW TRIGGERS; SHOW TRIGGERS LIKE '%ttlsa%'; SHOW TRIGGERS FROM database_name; -- 查看創建語句 SHOW CREATE TRIGGER ttlsa_users_ai; -- 信息元數據查詢 SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA='test' AND TRIGGER_NAME='ttlsa_users_au'\G -- 刪除觸發器 DROP TRIGGER ttlsa_users_ai;
-- 授權創建觸發器權限 GRANT TRIGGER ON database_name.table_name TO 'user'@'host'; -- 回收權限 REVOKE TRIGGER ON database_name.table_name FROM 'user'@'host';
注意: MySQL 5.7+ 將 TRIGGER 權限從 SUPER 中分離,單獨授予更安全。
PREPARE/EXECUTE)START TRANSACTION/COMMIT/ROLLBACK)max_sp_recursion_depth 限制(默認 0,禁用遞歸)--triggers,遷移時注意 DEFINER 賬號是否存在