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

Oracle 觸發器完整學習指南:從基礎語法到進階應用

     編輯:Oracle 資料庫相關知識

什麼是 Oracle 觸發器?

Oracle 觸發器是一種儲存於資料庫中的 PL/SQL 區塊,當特定事件發生時會自動執行。它不需要被明確呼叫,而是由資料庫系統根據定義的觸發條件自動啟動。觸發器是實現複雜業務邏輯、資料審計、衍生欄位自動生成以及強制資料一致性的強大工具。

觸發器的核心功能

  • 允許/限制資料修改:在特定時間或條件下控制 DML 操作
  • 自動生成衍生欄位:如自動遞增主鍵、計算欄位值
  • 強制資料一致性:跨表驗證、複雜檢查約束
  • 提供審計與日誌記錄:追蹤誰在何時做了什麼操作
  • 防止無效交易:攔截不符合業務規則的操作
  • 啟用複雜業務邏輯:封裝多步驟業務流程

觸發器的四大組成部分

以一個具體範例說明:

CREATE TRIGGER biufer_employees_department_id
BEFORE INSERT OR UPDATE
OF department_id
ON employees
REFERENCING OLD AS old_value NEW AS new_value
FOR EACH ROW
WHEN (new_value.department_id <> 80)
BEGIN
  :new_value.commission_pct := 0;
END;
/
  1. 觸發器名稱:採用命名慣例 biufer_表名_欄位名,其中 biufer 代表 Before Insert Update For Each Row
  2. 觸發語句:定義觸發時機(BEFORE/AFTER)、事件(INSERT/UPDATE/DELETE)、目標表、特定欄位、行級/語句級、相關變數別名
  3. 觸發器限制:WHEN 子句,僅當條件成立時執發觸發器本體
  4. 觸發操作:BEGIN ... END; 之間的 PL/SQL 程式碼,即觸發器主體

五大觸發器類型詳解

1. 語句觸發器

針對整個 DML 語句只觸發一次,無論影響多少行。適合安全檢查、整體日誌記錄。

-- 安全檢查範例:只有 DONNY 可修改 foo 表
CREATE TRIGGER biud_foo
BEFORE INSERT OR UPDATE OR DELETE
ON foo
BEGIN
  IF USER NOT IN ('DONNY') THEN
    RAISE_APPLICATION_ERROR(-20001, 'You don''t have access to modify this table.');
  END IF;
END;
/

判斷觸發操作類型:使用 INSERTING、UPDATING、DELETING 條件謂詞。

2. 行觸發器

包含 FOR EACH ROW 子句,對每一受影響的行都會觸發。可在本體中引用 :OLD 和 :NEW 伪記錄。

-- 主鍵自動遞增範例
CREATE SEQUENCE foo_seq;

CREATE OR REPLACE TRIGGER bifer_foo_id_pk
BEFORE INSERT ON foo
FOR EACH ROW
BEGIN
  SELECT foo_seq.NEXTVAL INTO :NEW.id FROM dual;
END;
/

REFERENCING 子句:可將 :OLD、:NEW 重命名,避免與資料表名稱衝突。

3. INSTEAD OF 觸發器

專用於視圖,取代對視圖的 DML 操作,實現不可更新視圖的更新功能。

CREATE OR REPLACE TRIGGER update_name_company_phone_book
INSTEAD OF UPDATE ON hr.company_phone_book
BEGIN
  UPDATE hr.employees
  SET first_name = SUBSTR(:NEW.name, INSTR(:NEW.name, ',') + 2),
      last_name  = SUBSTR(:NEW.name, 1, INSTR(:NEW.name, ',') - 1),
      phone_number = :NEW.phone_number,
      email      = :NEW.email
  WHERE employee_id = :OLD.emp_id;
END;

4. 系統事件觸發器

響應資料庫啟動/關閉、伺服器錯誤等系統級事件。

CREATE TRIGGER ad_startup
AFTER STARTUP ON DATABASE
BEGIN
  -- 執行啟動初始化邏輯
END;
/

5. 使用者事件觸發器

響應使用者登入/登出、DDL 操作(CREATE/ALTER/DROP 等)。

-- 記錄 DROP 物件操作
CREATE OR REPLACE TRIGGER log_drop_trigger
BEFORE DROP ON donny.schema
BEGIN
  INSERT INTO dropped_objects
  VALUES (ora_dict_obj_name, ora_dict_obj_type, SYSDATE);
END;
/

觸發器管理與注意事項

  • 啟用/停用:ALTER TRIGGER <name> ENABLE/DISABLE; 或 ALTER TABLE <table> ENABLE/DISABLE ALL TRIGGERS;
  • 交易控制:觸發器本體中不能使用 COMMIT/ROLLBACK,也不能執行 DDL(隱含提交)
  • 查詢觸發器:USER_TRIGGERS、DBA_TRIGGERS、ALL_TRIGGERS

最佳實踐建議

  1. 命名採用一致慣例,包含觸發時機、事件、層級、表名、欄位名
  2. 優先使用約束條件而非觸發器實現簡單驗證
  3. 避免在觸發器中執行耗時操作,影響 DML 效能
  4. 小心遞迴觸發器(觸發器內修改同一張表再次觸發)
  5. 善用 WHEN 子句減少不必要的觸發器執行
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved