觸發器是隨 DML 事件自動執行的存儲程序。本文系統講解創建語法、觸發時機/事件/粒度、:NEW/:OLD 伪列、業務校驗實戰、異常拋出最佳實踐。
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF}
{INSERT | UPDATE | DELETE | UPDATE OF col1, col2}
ON table_name
[FOR EACH ROW] -- 行級觸發器,省略則為語句級
[WHEN (condition)] -- 可選過濾條件
DECLARE
-- 變量聲明
BEGIN
-- PL/SQL 邏輯
EXCEPTION
-- 異常處理
END;
| 維度 | 選項 | 執行時機 | 典型用途 |
|---|---|---|---|
| 時機 | BEFORE | DML 執行前 | 數據校驗、自動填充、派生列計算 |
| AFTER | DML 執行後 | 審計日誌、異步通知、級聯維護 | |
| 粒度 | FOR EACH ROW | 每影響一行執行一次 | 行級業務邏輯、:NEW/:OLD 訪問 |
| 語句級(默認) | 整個 DML 執行一次 | 統計更新、跨表聚合 | |
| 事件 | INSERT/UPDATE/DELETE | 可組合 INSERT OR UPDATE OR DELETE | 多事件統一處理 |
CREATE OR REPLACE TRIGGER auth_secure
BEFORE INSERT OR UPDATE OR DELETE ON auths
BEGIN
IF TO_CHAR(SYSDATE, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN') IN ('SAT','SUN') THEN
RAISE_APPLICATION_ERROR(-20600, '不能在周末修改表 AUTH');
END IF;
END;
/
RAISE_APPLICATION_ERROR(error_num, msg):error_num 範圍 -20000 ~ -20999,msg 長度 ≤ 2KBNLS_DATE_LANGUAGE 確保星期縮寫穩定,避免會話語言導致判斷失效:NEW/:OLD,行級觸發器可訪問 :NEW.col(新值)、:OLD.col(舊值)ORA-04091)CREATE OR ALTER OR DROP ON SCHEMA/DATABASE、LOGON/LOGOFF/STARTUP/SHUTDOWN ON DATABASEDBMS_SCHEDULER 或 AQ 異步處理ORA-04091),用複合觸發器或 PRAGMA AUTONOMOUS_TRANSACTION 規避FORALL) 會逐行觸發行級觸發器,效能影響大,評估改用語句級或應用層邏輯FOLLOWS/PRECEDES (11g+) 顯式排序