首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 觸發器完整指南:類型、執行順序、複製同步影響與經典避坑案例

     編輯:MySQL 綜合教學

1. 觸發器基礎語法

CREATE TRIGGER trigger_name trigger_time trigger_event
ON tbl_name FOR EACH ROW trigger_stmt
  • trigger_time:BEFORE / AFTER
  • trigger_event:INSERT / UPDATE / DELETE
  • 單表最多 6 個觸發器(3 事件 × 2 時機),同類型不可重複。
  • 語句體可用 BEGIN ... END 包裹多條 SQL,支持 IF/ELSE、循環等流程控制。
  • OLD(唯讀)與 NEW(可寫)引用行數據:INSERT 只有 NEW,DELETE 只有 OLD,UPDATE 兩者皆有。

2. 管理與查看

SHOW TRIGGERS;                    -- 全庫
SHOW TRIGGERS FROM db LIKE 'pat%'; -- 指定庫模糊
SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_NAME='xxx'\G; -- 詳情
DROP TRIGGER [schema_name.]trigger_name; -- 刪除

3. 執行順序與事務行為(基於 InnoDB / MySQL 5.0.45 源碼驗證)

場景結果源碼邏輯
BEFORE 觸發器失敗主 SQL 不執行,直接跳轉錯誤處理process_triggers(BEFORE) 失敗 → goto err2
主 SQL 執行失敗AFTER 觸發器不執行update_row 失敗 → goto err,跳過 AFTER
AFTER 觸發器失敗主 SQL 回滾(InnoDB)process_triggers(AFTER) 失敗 → goto err2 → 事務標記回滾

非事務引擎(MyISAM)無法回滾,失敗前的更改已生效。

4. 複雜 UPDATE 多表時的觸發器執行順序陷阱

源碼顯示:for (cur_table=update_tables; ...) 依次處理每張表的 BEFORE → UPDATE → AFTER。
結論:多表 UPDATE 時,觸發器見到的「其他表數據」取決於該表在更新順序中的位置。
最佳實踐:避免在觸發器中查詢同一 SQL 正在更新的其他表;拆分為單表操作或應用層協調。

5. 主從複製中的觸發器行為

  • 觸發器定義語句(CREATE/DROP)會寫入 Binlog,同步到從庫。
  • 從庫觸發器執行失敗 → SQL 線程停止(Slave_SQL_Running: No)。
  • 若從庫已存在同名同類型觸發器,主庫 CREATE 同步會報錯;DROP 不存在的觸發器同步不報錯。

6. 經典避坑案例

案例 1:多表 UPDATE 讀到舊值

觸發器建在 test_info 上,SQL 先更新 test_info 再更新 wext2,AFTER 觸發器讀 wext2 仍是舊值。調換表順序即可讀到新值。

案例 2:MySQL 5.0.19 ALTER TABLE 導致觸發器消失

該版本 Bug:修改表結構時 information_schema.TRIGGERS 記錄被誤刪。5.0.45 已修復。

案例 3:DROP TABLE 連帶刪除觸發器

主庫 DROP TABLE wnegative 同步到從庫,觸發器隨表消失。重建表不會自動恢復觸發器,需重新 CREATE TRIGGER。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved