首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 觸發器進階:五大類型、行級/語句級對比與實戰模式(二)

     編輯:Oracle 資料庫相關知識

一、觸發器類型總覽

類型觸發時機執行頻率典型用途
語句級BEFORE/AFTER每條 DML 語句一次審計日志、安全檢查、統計維護
行級BEFORE/AFTER每受影響行一次自動填充派生列、複雜業務規則、跨表同步
INSTEAD OF替代 DML每行一次視圖不可更新時重定向操作
系統事件啟動/關閉/錯誤事件發生時自動啟動作業、記錄實例狀態
用戶事件登錄/登出/DDL事件發生時審計用戶行為、動態權限控制

二、語句級觸發器實戰

CREATE OR REPLACE TRIGGER tri_test
AFTER INSERT OR UPDATE OR DELETE ON test
BEGIN
  IF INSERTING THEN
    DBMS_OUTPUT.PUT_LINE('插入');
  ELSIF UPDATING THEN
    DBMS_OUTPUT.PUT_LINE('修改');
  ELSIF DELETING THEN
    DBMS_OUTPUT.PUT_LINE('刪除');
  END IF;
END;

特點:無 :NEW/:OLD 伪記錄,適合記錄「發生了什麼操作」而非「具體數據變化」。

三、行級觸發器實戰:自動生成主鍵 + 禁止修改主鍵

CREATE TABLE test (sid NUMBER, sname VARCHAR2(20));
CREATE SEQUENCE seq_test;

CREATE OR REPLACE TRIGGER tri_test
BEFORE INSERT OR UPDATE OF sid ON test
FOR EACH ROW
BEGIN
  IF INSERTING THEN
    SELECT seq_test.NEXTVAL INTO :NEW.sid FROM dual;
  ELSE
    RAISE_APPLICATION_ERROR(-20020, '不允許更新 ID 值!');
  END IF;
END;

關鍵點:

  • FOR EACH ROW 聲明行級;
  • :NEW.sid 賦值生效於插入;
  • RAISE_APPLICATION_ERROR 中斷非法更新。

四、行級 vs 語句級選型指南

場景推薦類型理由
記錄操作審計(誰、何時、什麼表、什麼操作)語句級開銷小、無需逐行上下文
自動填充創建時間/修改時間/操作人行級需訪問 :NEW 每行
複雜跨表業務邏輯(如庫存扣減、賬戶轉賬)行級需逐行協調事務
防止周末/節假日修改核心表語句級一次判斷覆蓋整條語句

五、性能與陷阱提醒

  • 行級觸發器會逐行切換上下文,大批量 DML(萬行以上)性能顯著下降 → 改用批量處理或應用層邏輯;
  • 避免在觸發器中執行長耗時操作(網絡調用、大量查詢),導致鎖持有時間過長;
  • 觸發器異常將導致觸發語句回滾,務必捕獲預期異常,不可預期異常拋出;
  • 循環觸發風險:A 表觸發器修改 B 表,B 表觸發器再修改 A 表 → 設置包級標誌變量防重入。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved