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

Oracle Trigger 觸發器完整指南:類型、語法、啟停與最佳實踐

     編輯:Oracle 資料庫基礎

觸發器分類

建立語法

CREATE [OR REPLACE] TRIGGER [schema.]trigger_name
{BEFORE | AFTER | INSTEAD OF} event
ON {table_name | view_name | DATABASE}
[FOR EACH ROW [WHEN (condition)]]
[FOLLOWS | PRECEDES other_trigger]  -- 11g+ 指定觸發順序
[ENABLE | DISABLE]
DECLARE
  -- 區域變數
BEGIN
  -- PL/SQL 區塊
  -- 行級可用 :OLD、:NEW 偽記錄
END;
/

關鍵概念

  • 行級 vs 陳述式級:FOR EACH ROW 表示受影響每行觸發一次;省略則整個 DML 陳述式只觸發一次。
  • :OLD / :NEW:行級觸發器專用偽記錄。
    :OLD.col = 修改前值(INSERT 為 NULL),
    :NEW.col = 修改後值(DELETE 為 NULL)。
  • INSTEAD OF:僅用於 View,取代 DML 操作,實現不可更新 View 的更新邏輯。
  • WHEN 條件:行級觸發器可加 WHEN (condition) 過濾,減少不必要觸發開銷。

實用範例

1. 稽核記錄(行級 AFTER)

CREATE OR REPLACE TRIGGER trg_emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW
BEGIN
  INSERT INTO emp_audit (empno, oper_type, oper_time, old_sal, new_sal)
  VALUES (
    NVL(:NEW.empno, :OLD.empno),
    CASE WHEN INSERTING THEN 'INS' WHEN UPDATING THEN 'UPD' ELSE 'DEL' END,
    SYSDATE,
    :OLD.sal,
    :NEW.sal
  );
END;
/

2. 自動維護衍生欄(BEFORE)

CREATE OR REPLACE TRIGGER trg_emp_upd_chg
BEFORE UPDATE ON emp
FOR EACH ROW
WHEN (OLD.sal != NEW.sal)  -- 僅薪資變動時觸發
BEGIN
  :NEW.last_sal_chg := SYSDATE;
  :NEW.sal_chg_count := NVL(:OLD.sal_chg_count, 0) + 1;
END;
/

3. 防止誤刪重要表(DDL BEFORE)

CREATE OR REPLACE TRIGGER trg_prevent_drop
BEFORE DROP ON DATABASE
WHEN (ora_dict_obj_name IN ('EMP', 'DEPT') AND ora_dict_obj_type = 'TABLE')
BEGIN
  RAISE_APPLICATION_ERROR(-20001, '禁止刪除核心業務表!');
END;
/

管理命令

事件類型觸發時機支援 FOR EACH ROW典型用途
DML (INSERT/UPDATE/DELETE)BEFORE / AFTER / INSTEAD OF是(行級)稽核、衍生欄維護、跨表同步
DDL (CREATE/ALTER/DROP)BEFORE / AFTER否(陳述式級)結構變更稽核、防誤刪
Database (STARTUP/SHUTDOWN/LOGON/LOGOFF/SERVERERROR)AFTER (STARTUP/LOGON) / BEFORE (SHUTDOWN/LOGOFF)否登入審計、啟動初始化、錯誤通知
操作語法
啟用單一觸發器ALTER TRIGGER trg_name ENABLE;
停用單一觸發器ALTER TRIGGER trg_name DISABLE;
啟用表上所有觸發器ALTER TABLE tbl_name ENABLE ALL TRIGGERS;
停用表上所有觸發器ALTER TABLE tbl_name DISABLE ALL TRIGGERS;
刪除觸發器DROP TRIGGER trg_name;

最佳實踐與避坑指南

  1. 避免觸發器鏈式反應:觸發器中執行 DML 可能再觸發其他觸發器,導致遞歸或效能雪崩。必要時用 DBMS_UTILITY.FORMAT_CALL_STACK 檢測深度。
  2. 謹慎使用 BEFORE 修改 :NEW:邏輯錯誤可能導致資料不一致;複雜驗證建議放在 Application 層或 CHECK CONSTRAINT。
  3. 大量資料操作時暫停觸發器:ALTER TABLE ... DISABLE ALL TRIGGERS → 執行批次 → ENABLE ALL TRIGGERS。
  4. 命名規範:trg____,如 trg_emp_beu_audit。
  5. 文件化:在註釋說明觸發目的、影響範圍、例外處理邏輯。
    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved