觸發器是 MySQL 中強大的自動化機制,能在資料異動前後自動執行預定義邏輯。本文系統講解觸發器四要素、建立語法、刪除方法,並以「訂單-商品」庫存聯動為核心案例,展示 INSERT/UPDATE/DELETE 三種觸發場景的實戰寫法。
| 要素 | 說明 | 可選值 |
|---|---|---|
| 觸發時間 | 相對於觸發事件的執行時機 | BEFORE / AFTER |
| 觸發地點 | 監聽的目標表 | 具體表名 |
| 監聽操作 | 觸發條件事件 | INSERT / UPDATE / DELETE |
| 觸發動作 | 執行的 SQL 語句 | INSERT / UPDATE / DELETE / CALL 等 |
DELIMITER $ -- 修改結束符,避免 BEGIN...END 內部 ; 衝突
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
FOR EACH ROW
BEGIN
-- 觸發邏輯:可包含多條 SQL
SQL 语句;
END$
DELIMITER ; -- 恢復預設結束符
DROP TRIGGER [IF EXISTS] trigger_name;
測試表結構:
-- 商品表
CREATE TABLE goods (
id INT PRIMARY KEY,
name VARCHAR(50),
num INT -- 庫存數量
);
-- 訂單表
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
gid INT, -- 商品 ID
much INT -- 購買數量
);
CREATE TRIGGER tg_after_insert_order
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
UPDATE goods
SET num = num - NEW.much
WHERE id = NEW.gid;
END$
關鍵點:NEW 代表新插入的行,NEW.欄位名 取得欄位值。
CREATE TRIGGER tg_after_delete_order
AFTER DELETE ON orders
FOR EACH ROW
BEGIN
UPDATE goods
SET num = num + OLD.much
WHERE id = OLD.gid;
END$
關鍵點:OLD 代表被刪除的行。
CREATE TRIGGER tg_after_update_order
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
UPDATE goods
SET num = num + OLD.much - NEW.much
WHERE id = OLD.gid;
END$
邏輯:先加回舊數量,再扣減新數量,差值即為庫存變動量。
| 特性 | BEFORE | AFTER |
|---|---|---|
| 執行順序 | 先觸發,再執行 DML | 先執行 DML,再觸發 |
| 典型用途 | 資料驗證、自動填充、阻止非法操作 | 日誌記錄、聯動更新、異步通知 |
| 可修改 NEW 值 | 是 (SET NEW.col = val) | 否 |
| 事務關係 | 同一事務內 | 同一事務內 |
TRIGGER 權限 (MySQL 5.1.6+)mysqldump --triggers 導出觸發器,預設已包含SHOW TRIGGERS;
-- 或查詢系統表
SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA='db_name';
MySQL 觸發器是實現資料完整性、業務聯動、審計日誌的利器。掌握 NEW/OLD 伪行引用、BEFORE/AFTER 時機選擇、複雜邏輯封裝等核心技巧,能讓資料庫層承擔更多業務邏輯,減少應用層複雜度。但需權衡效能與維護性,避免過度依賴導致「隱藏邏輯」難以追蹤。