Oracle 觸發器是一種儲存於資料庫中的 PL/SQL 區塊,當特定事件發生時會自動執行。它不需要被明確呼叫,而是由資料庫系統根據定義的觸發條件自動啟動。觸發器是實現複雜業務邏輯、資料審計、衍生欄位自動生成以及強制資料一致性的強大工具。
以一個具體範例說明:
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;
/
biufer_表名_欄位名,其中 biufer 代表 Before Insert Update For Each RowWHEN 子句,僅當條件成立時執發觸發器本體BEGIN ... END; 之間的 PL/SQL 程式碼,即觸發器主體針對整個 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 條件謂詞。
包含 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 重命名,避免與資料表名稱衝突。
專用於視圖,取代對視圖的 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;
響應資料庫啟動/關閉、伺服器錯誤等系統級事件。
CREATE TRIGGER ad_startup
AFTER STARTUP ON DATABASE
BEGIN
-- 執行啟動初始化邏輯
END;
/
響應使用者登入/登出、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_TRIGGERSWHEN 子句減少不必要的觸發器執行