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

Oracle 內建觸發器範例解析:DDL 審計、啟動遷移、角色清理、刪除備份四大經典模式

     編輯:Oracle 資料庫基礎

Oracle 資料庫內建數個系統級觸發器,展示了 AFTER STARTUP、AFTER DROP ON DATABASE、BEFORE DELETE FOR EACH ROW 等核心觸發時機與實作模式。本文解析四大經典範例,並提煉可直接套用的觸發器模板。

一、MDSYS.SDO_DROP_USER - DDL 審計與清理

CREATE OR REPLACE TRIGGER mdsys.sdo_drop_user
AFTER DROP ON DATABASE
DECLARE
  stmt VARCHAR2(200);
BEGIN
  IF ora_dict_obj_type = 'USER' THEN
    stmt := 'DELETE FROM sdo_geom_metadata_table WHERE sdo_owner = ''' || ora_dict_obj_name || '''';
    EXECUTE IMMEDIATE stmt;
  END IF;
END;
/

模式:AFTER DROP ON DATABASE + ora_dict_obj_type/name 判斷被刪除物件類型與名稱,動態執行清理 SQL。適用於:自動清理被刪除使用者的空間中繼資料、審計表、自訂快取表等。

二、SYS.AURORA$SERVER$STARTUP - 實例啟動初始化

CREATE OR REPLACE TRIGGER sys.aurora$server$startup
AFTER STARTUP ON DATABASE
CALL dbms_java.server_startup;

模式:AFTER STARTUP ON DATABASE + CALL 直接呼叫封裝好的初始化程序。適用於:JVM 初始化、排程作業啟動、快取預熱、外部服務註冊。

三、SYS.JIS$ROLE_TRIGGER$ - 角色刪除級聯清理

CREATE OR REPLACE TRIGGER sys.jis$role_trigger$
AFTER DROP ON DATABASE
WHEN (ora_dict_obj_type = 'ROLE')
BEGIN
  sns_context.role_dropped(ora_dict_obj_name);
  http_security_cascade.principal_dropped(ora_dict_obj_name);
END;
/

模式:WHEN 子句過濾事件類型,減少觸發器本體執行開銷。適用於:角色/使用者/配置檔刪除時的跨系統級聯清理(SSO、權限快取、審計日誌)。

四、YSPJ.T_BILL_REMAIN_DEL - 刪除前備份(列級觸發器)

CREATE OR REPLACE TRIGGER yspj.t_bill_remain_del
BEFORE DELETE ON bill_remain
FOR EACH ROW
BEGIN
  INSERT INTO bill_remain_tiger
  VALUES (
    :old.bill_remainid, :old.bill_typeid, :old.remain_num,
    :old.add_time,    :old.org_id,     :old.state,
    :old.bill_id,     '刪除記錄',       SYSDATE, USER
  );
END;
/

模式:BEFORE DELETE FOR EACH ROW + :OLD 伪記錄捕獲完整舊值,寫入審計/備份表。適用於:關鍵業務表刪除審計、軟刪除實作、異動追蹤。

五、觸發器開發黃金法則

原則說明
盡量用 BEFORE可修改 :NEW 值、阻止操作(RAISE_APPLICATION_ERROR),效能優於 AFTER。
避免觸發器鏈觸發器中再觸發其他觸發器,極難除錯;改用封裝程序統一協調。
FOR EACH ROW 慎用逐列觸發,大量 DML 時開銷巨大;改用 STATEMENT 級 + 臨時表/複合觸發器 (11g+)。
不在觸發器中 COMMIT觸發器屬於觸發交易一部分,COMMIT 會導致 ORA-04092;交易控制留給呼叫端。
使用複合觸發器11g+ COMPOUND TRIGGER 可在同一觸發器中處理 BEFORE STATEMENT / BEFORE EACH ROW / AFTER EACH ROW / AFTER STATEMENT,解決「需彙總後再處理」場景。
命名規範trg___,如 trg_emp_biu_audit。

六、常見觸發器模板(複製即用)

1. 審計觸發器(INSERT/UPDATE/DELETE 通用)

CREATE OR REPLACE TRIGGER trg_emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW
DECLARE
  v_op VARCHAR2(10);
BEGIN
  v_op := CASE WHEN INSERTING THEN 'INS' WHEN UPDATING THEN 'UPD' ELSE 'DEL' END;
  INSERT INTO emp_audit (empno, ename, sal, op_type, op_time, op_user)
  VALUES (COALESCE(:NEW.empno, :OLD.empno),
          COALESCE(:NEW.ename, :OLD.ename),
          COALESCE(:NEW.sal,   :OLD.sal),
          v_op, SYSDATE, USER);
END;
/

2. 自動填充建立/修改時間

CREATE OR REPLACE TRIGGER trg_emp_timestamps
BEFORE INSERT OR UPDATE ON emp
FOR EACH ROW
BEGIN
  IF INSERTING THEN
    :NEW.created_at := SYSDATE;
    :NEW.created_by := USER;
  END IF;
  :NEW.updated_at := SYSDATE;
  :NEW.updated_by := USER;
END;
/

3. 防止周末刪除核心資料

CREATE OR REPLACE TRIGGER trg_core_protect
BEFORE DELETE ON core_table
BEGIN
  IF TO_CHAR(SYSDATE, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN') IN ('SAT','SUN') THEN
    RAISE_APPLICATION_ERROR(-20001, '周末禁止刪除核心資料');
  END IF;
END;
/

善用 Oracle 內建觸發器範例與上述模板,能快速構建健壯的資料完整性、審計追蹤、自動化維護機制,將業務規則下沉至資料庫層,降低應用層複雜度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved