| 事件 | NEW | OLD |
| INSERT | 新插入行 (可修改) | 不可用 |
| UPDATE | 更新後新值 (可修改) | 更新前舊值 (唯讀) |
| DELETE | 不可用 | 被刪除行 (唯讀) |
存取方式:NEW.column_name、OLD.column_name
實戰範例:審計日誌、資料同步、業務驗證
範例 1:插入審計日誌 (AFTER INSERT)
DELIMITER //
CREATE TRIGGER trg_after_users_insert
AFTER INSERT ON users
FOR EACH ROW
BEGIN
INSERT INTO audit_log (table_name, action, record_id, new_data, created_at)
VALUES ('users', 'INSERT', NEW.id,
JSON_OBJECT('name', NEW.name, 'email', NEW.email),
NOW());
END //
DELIMITER ;
範例 2:更新前驗證/修正 (BEFORE UPDATE)
DELIMITER //
CREATE TRIGGER trg_before_products_update
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
-- 價格不得為負
IF NEW.price < 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '價格不能為負數';
END IF;
-- 自動更新修改時間
SET NEW.updated_at = NOW();
-- 記錄價格變更歷史
IF OLD.price != NEW.price THEN
INSERT INTO price_history (product_id, old_price, new_price, changed_at)
VALUES (OLD.id, OLD.price, NEW.price, NOW());
END IF;
END //
DELIMITER ;
範例 3:刪除前備份/級聯處理 (BEFORE DELETE)
DELIMITER //
CREATE TRIGGER trg_before_orders_delete
BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
-- 歸檔刪除訂單
INSERT INTO orders_archive SELECT * FROM orders WHERE id = OLD.id;
-- 檢查是否有關聯付款 (拒絕刪除)
IF EXISTS (SELECT 1 FROM payments WHERE order_id = OLD.id AND status = 'paid') THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '已付款訂單不可刪除';
END IF;
END //
DELIMITER ;
管理指令大全
查看觸發器
-- 列出所有觸發器
SHOW TRIGGERS;
-- 或特定資料庫
SHOW TRIGGERS FROM db_name;
-- 查看特定觸發器建立語句
SHOW CREATE TRIGGER trg_after_users_insert;
-- 查看觸發器元資料
SELECT * FROM information_schema.TRIGGERS
WHERE TRIGGER_SCHEMA = 'db_name';
刪除觸發器
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name;
-- 範例
DROP TRIGGER IF EXISTS trg_after_users_insert;