通常情況下,Oracle數據庫禁止在行級觸發器或行級觸發器所調用的子程序中使用查詢語句。但是,面對復雜的業務邏輯,不可避免的要使用查詢語句。
當在行級觸發器中使用查詢語句時,Oracle數據庫會拋出ORA-04091異常。
Oracle官方文檔中對ORA-04091異常的說明如下:
ORA-04091: table string.string is mutating, trigger/function may not see it
Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
如果必須要在Trigger中使用查詢語句,Oracle也提供了一種途徑。
下面以簡單的代碼為例做說明:
1 CREATE OR REPLACE TRIGGER TRG_TEST 2 BEFORE INSERT OR UPDATE OR DELETE ON SCOTT.EMP 3 FOR EACH ROW -- 行級觸發器 4 DECLARE 5 PRAGMA AUTONOMOUS_TRANSACTION; -- 解決行級觸發器不能使用查詢語句的關鍵 6 7 V_COUNT PLS_INTEGER; 8 BEGIN 9 SELECT COUNT(*) INTO V_COUNT FROM SCOTT.EMP; 10 IF V_COUNT > 0 THEN 11 -- DO SOMETHING 12 NULL; 13 END IF; 14 15 COMMIT; -- 提交 16 EXCEPTION 17 WHEN OTHERS THEN 18 ROLLBACK; -- 回滾 19 END TRG_TEST;
如上面代碼所示:在定義Trigger時,聲明其事務的提交模式為PRAGMA AUTONOMOUS_TRANSACTION。
但是,用戶必須自己提交或回滾事務。
對於PRAGMA AUTONOMOUS_TRANSACTION的說明請參考Oracle官方文檔。