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

Oracle 觸發器類型、語法與設計規範完整指南

     編輯:Oracle 資料庫基礎

觸發器是針對特定事件自動執行的 PL/SQL 區塊,分為行級、語句級、INSTEAD OF、Schema 級、Database 級五大類。本文詳細解析各類型語法、適用場景、特殊變數、啟用/停用與設計黃金法則。

五大觸發器類型對照

類型觸發時機執行頻率典型用途
行級BEFORE/AFTER INSERT/UPDATE/DELETE每影響一行執行一次自動填欄位、複雜檢核、審計日誌
語句級BEFORE/AFTER INSERT/UPDATE/DELETE每個 DML 語句執行一次統計影響筆數、整體檢核
INSTEAD OF針對 VIEW 的 DML每行/語句視定義而定使不可更新視圖可更新
Schema 級DDL 事件每個 DDL 執行一次記錄結構變更、防刪保護
Database 級STARTUP/SHUTDOWN/LOGON/LOGOFF/SERVERERROR每個事件一次啟動初始化、登入審計、錯誤通知

建立語法通用模板


CREATE [OR REPLACE] TRIGGER trigger_name
  {BEFORE | AFTER | INSTEAD OF}
  {INSERT | UPDATE [OF col] | DELETE} ON table_name
  [FOR EACH ROW]                    -- 行級必加
  [WHEN (condition)]                -- 選擇性條件
DECLARE
  -- 宣告區
BEGIN
  -- 執行區
EXCEPTION
  -- 異常處理
END;

關鍵特殊變數::NEW / :OLD

  • 僅行級觸發器(FOR EACH ROW)可用。
  • :NEW.col:新值(INSERT/UPDATE 有,DELETE 為 NULL)。
  • :OLD.col:舊值(UPDATE/DELETE 有,INSERT 為 NULL)。
  • 可在 BEFORE 觸發器中修改 :NEW.col := ... 實現自動賦值。

實戰範例

範例 1:行級 - 自動產生序列主鍵、禁止更新 PK


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

範例 2:行級 - 自動轉大寫


CREATE OR REPLACE TRIGGER trg_emp_job
BEFORE INSERT OR UPDATE OF job ON emp
FOR EACH ROW
BEGIN
  :NEW.job := UPPER(:NEW.job);
END;

範例 3:語句級 - 記錄操作類型


CREATE OR REPLACE TRIGGER trg_test_stmt
AFTER INSERT OR UPDATE OR DELETE ON test
BEGIN
  IF INSERTING THEN DBMS_OUTPUT.PUT_LINE('INSERT');
  ELSIF UPDATING THEN DBMS_OUTPUT.PUT_LINE('UPDATE');
  ELSIF DELETING THEN DBMS_OUTPUT.PUT_LINE('DELETE');
  END IF;
END;

範例 4:INSTEAD OF - 視圖更新


CREATE OR REPLACE TRIGGER trg_v_emp_iof
INSTEAD OF INSERT OR UPDATE ON v_emp
REFERENCING NEW AS n
FOR EACH ROW
BEGIN
  INSERT INTO emp (empno, ename, job) VALUES (:n.empno, :n.ename, :n.job);
END;

範例 5:Schema 級 - 記錄 DDL


CREATE OR REPLACE TRIGGER trg_ddl_log
AFTER DROP ON SCHEMA
BEGIN
  INSERT INTO ddl_log (obj_name, obj_type, user_name, op_time)
  VALUES (ORA_DICT_OBJ_NAME, ORA_DICT_OBJ_TYPE, USER, SYSDATE);
END;

範例 6:Database 級 - 啟動初始化


CREATE OR REPLACE TRIGGER trg_startup
AFTER STARTUP ON DATABASE
BEGIN
  EXECUTE IMMEDIATE 'ALTER SYSTEM SET ...';  -- 動態調整參數
END;

管理命令

ALTER TRIGGER trg_name DISABLE;ALTER TRIGGER trg_name ENABLE;ALTER TABLE table_name DISABLE ALL TRIGGERS;ALTER TABLE table_name ENABLE ALL TRIGGERS;DROP TRIGGER trg_name;
操作命令
停用單一觸發器
啟用單一觸發器
停用表上所有觸發器
啟用表上所有觸發器
刪除觸發器

設計黃金法則(必讀)

  1. 職責單一:一個觸發器只做一件事,避免巨大觸發器難以維護。
  2. 不重複資料庫內建功能:PK/FK/Not Null/Check 約束交給約束機制,觸發器處理無法用約束表達的複雜邏輯。
  3. 控制代碼行數:超過 50 行考慮拆分為存儲過程由觸發器呼叫。
  4. 嚴禁遞迴觸發:觸發器內執行 DML 再觸發同觸發器 → 無限迴圈。若必要,用套件變數旗標控制。
  5. 觸發器屬於 Schema 物件:表刪除時關聯觸發器自動刪除。
  6. 同一時機同一張表最多三個觸發器:各一個 INSERT/UPDATE/DELETE(舊版限制,新版可多個但需指定 FOLLOWS 排序)。
  7. SELECT 無觸發器:唯讀操作不觸發,改用 VPD/FGAC 或 View 控制。

刪除觸發器語法

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