通常情况下,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官方文档。