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

Oracle 觸發器語法詳解:BEFORE/AFTER、行級/語句級、RAISE_APPLICATION_ERROR 實戰

     編輯:Oracle 資料庫基礎

觸發器是隨 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;

核心概念對照

維度選項執行時機典型用途
時機BEFOREDML 執行前數據校驗、自動填充、派生列計算
AFTERDML 執行後審計日誌、異步通知、級聯維護
粒度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 長度 ≤ 2KB
  • 使用 NLS_DATE_LANGUAGE 確保星期縮寫穩定,避免會話語言導致判斷失效
  • 語句級觸發器無 :NEW/:OLD,行級觸發器可訪問 :NEW.col(新值)、:OLD.col(舊值)

進階模式

  • INSTEAD OF 觸發器:用於視圖,將 DML 轉發到底表,實現視圖可更新
  • 複合觸發器 (11g+):單觸發器包含 BEFORE STATEMENT、BEFORE ROW、AFTER ROW、AFTER STATEMENT 四個時機塊,解決「變更表」錯誤 (ORA-04091)
  • DDL/系統事件觸發器:CREATE OR ALTER OR DROP ON SCHEMA/DATABASE、LOGON/LOGOFF/STARTUP/SHUTDOWN ON DATABASE

避坑清單

  1. 避免觸發器中執行長耗時邏輯(發郵件、HTTP 調用),改用 DBMS_SCHEDULER 或 AQ 異步處理
  2. 行級觸發器中禁止查詢/修改同一表(觸發 ORA-04091),用複合觸發器或 PRAGMA AUTONOMOUS_TRANSACTION 規避
  3. 批量 DML (FORALL) 會逐行觸發行級觸發器,效能影響大,評估改用語句級或應用層邏輯
  4. 觸發器順序不可控,多觸發器同事件同時機時用 FOLLOWS/PRECEDES (11g+) 顯式排序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved