首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 5.0 Trigger 觸發器完整教學:語法、權限、NEW/OLD、CHECK 替代、已知 Bug

     編輯:MySQL 資料庫相關知識

為什麼需要 Trigger?

  • 資料完整性:攔截/修正髒資料 (替代 CHECK CONSTRAINT)
  • 稽核追蹤:記錄資料變更歷程
  • 衍生資料維護:同步更新彙總表、快取表
  • 商業規則強制:在資料庫層集中邏輯

語法結構

CREATE TRIGGER <trigger_name>
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON <table_name>
FOR EACH ROW
<trigger_body>
  • 命名慣例:表名_時機_事件,如 t26_bu (BEFORE UPDATE)
  • 時機:BEFORE (可修正 NEW 值) / AFTER (不可修改 NEW)
  • 事件:INSERT / UPDATE / DELETE
  • 粒度:FOR EACH ROW 逐列觸發 (MySQL 僅支援列級)
  • 主體:合法 SQL 語句,含複合語句 BEGIN...END,受函數相同限制 (不可存取表、不可動態 SQL 等)

NEW / OLD 過渡變數

事件可用說明
INSERTNEW新列值
DELETEOLD舊列值
UPDATENEW, OLD修改前後值
CREATE TRIGGER t21_au BEFORE UPDATE ON t22
FOR EACH ROW
BEGIN
  SET @old = OLD.s1;
  SET @new = NEW.s1;
END;//

實戰:用 BEFORE Trigger 實現 CHECK 約束

MySQL 不支援 CHECK,但可用 Trigger 模擬:

CREATE TABLE t25 (s1 INT, s2 CHAR(5), PRIMARY KEY(s1)) ENGINE=INNODB;

CREATE TRIGGER t25_bi BEFORE INSERT ON t25
FOR EACH ROW
IF LEFT(NEW.s2,1) <> 'A' THEN SET NEW.s1 = 0; END IF;//

CREATE TRIGGER t25_bu BEFORE UPDATE ON t25
FOR EACH ROW
IF LEFT(NEW.s2,1) <> 'A' THEN SET NEW.s1 = 0; END IF;//

違規時將 PK 設為 0 觸發主鍵衝突,達到攔截效果。

權限模型

  • 需 CREATE TRIGGER 權限 (5.0 預設僅 root 擁有)
  • 未來版本將支援 GRANT CREATE TRIGGER ON table TO user

已知 Bug (5.0.3 版本)

  • Bug#5859:DROP TABLE 不會自動刪除關聯 Trigger
  • Bug#5892:Trigger 命名空間錯誤,需 DROP TRIGGER schema.trigger
  • Bug#5894:ALTER TABLE 有 Trigger 時可能損壞資料庫 → 嚴禁對有 Trigger 的表執行 ALTER
Trigger 較新,生產環境謹慎使用,建議先在測試庫驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved