CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE [OF column]} ON table_name
[FOR EACH ROW]
[WHEN (condition)]
BEGIN
-- PL/SQL 區塊
END;
/
| 子句 | 說明 |
|---|---|
| BEFORE / AFTER | 觸發時機:DML 執行前/後。BEFORE 可修改 :NEW 值;AFTER 可讀取最終狀態。 |
| FOR EACH ROW | **列級觸發器**:每影響一列觸發一次。省略則為**陳述式觸發器**,整條 DML 觸發一次。 |
| :NEW / :OLD | 偽記錄::NEW.col 新值,:OLD.col 舊值。INSERT 僅有 :NEW,DELETE 僅有 :OLD,UPDATE 兩者皆有。 |
| WHEN | 列級觸發器可選條件,僅符合條件才執行本體,減少開銷。 |
RAISE_APPLICATION_ERROR 回滾。-- 1. 建表
CREATE TABLE t1 (id NUMBER, name NVARCHAR2(8));
-- 2. 建 Sequence
CREATE SEQUENCE t1_id INCREMENT BY 1 START WITH 1 MAXVALUE 9999999;
-- 3. 建 Trigger
CREATE OR REPLACE TRIGGER tig_insert_t1
BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
IF :NEW.id IS NULL THEN
SELECT t1_id.NEXTVAL INTO :NEW.id FROM dual;
END IF;
END;
/
測試:INSERT INTO t1(name) VALUES('abc'); → id 自動填入 1,2,3…
CREATE OR REPLACE PROCEDURE proc_create_seq_trig(p_tables IN VARCHAR2) AS
v_sql VARCHAR2(4000);
v_tname VARCHAR2(50);
v_pid VARCHAR2(50);
BEGIN
-- 解析逗號分隔表名,迴圈為每張表建 Sequence + Trigger
-- 略(動態 SQL 組裝 CREATE SEQUENCE / CREATE TRIGGER)
END;
/
適用於批量為現有表補裝自增主鍵,減少手工重複工作。
WHEN 防禦
CREATE OR REPLACE TRIGGER trg_emp_sal
AFTER UPDATE OF sal ON emp
FOR EACH ROW
WHEN (NEW.sal != OLD.sal) -- 僅薪資真正變動時觸發
BEGIN
UPDATE dept SET total_sal = total_sal + :NEW.sal - :OLD.sal
WHERE deptno = :NEW.deptno;
END;
單一 Trigger 內包含 BEFORE STATEMENT、BEFORE EACH ROW、AFTER EACH ROW、AFTER STATEMENT 四個時機區塊,解決「列級需彙總後在陳述式級處理」的需求(如大量收集欄位變化最後一次性寫入稽核表),避免 ORA-04091 變動表錯誤。
CREATE OR REPLACE TRIGGER trg_ddl AFTER DDL ON SCHEMA BEGIN ... END;:記錄結構變更。AFTER LOGON ON DATABASE、AFTER STARTUP ON DATABASE:登入稽核、啟動初始化。TRG___(如 TRG_EMP_BIR_UPD)。
- 文件化:
COMMENT ON TRIGGER trg_name IS '...';。
結語
Trigger 是資料庫端主動行為的核心機制。掌握 BEFORE/AFTER、:NEW/:OLD、FOR EACH ROW 三大支柱,配合六大功能場景判斷,並遵循「約束優先、Trigger 補充、防遞迴、控開銷」原則,即能善用 Trigger 強化資料完整性與業務自動化。
- 上一篇文章: Oracle 7.x 回滾段資料檔誤刪救援:Mount 階段離線 Drop 重建全流程
- 下一篇文章: Oracle 非同步預存程序實戰:DBMS_JOB + DBMS_PIPE 實現長任務監控
Copyright © 程式碼之家 All Rights Reserved