Sql 仅在旧=新上进行选择时获取变异表(ORA-04091)
我在oracle中对触发器进行简单的选择计数时遇到问题。我一直收到ORA-04091:Sql 仅在旧=新上进行选择时获取变异表(ORA-04091),sql,oracle,plsql,oracle10g,oracle-sqldeveloper,Sql,Oracle,Plsql,Oracle10g,Oracle Sqldeveloper,我在oracle中对触发器进行简单的选择计数时遇到问题。我一直收到ORA-04091: AFTER INSERT OR UPDATE ON table FOR EACH ROW DECLARE legal_amount INT; BEGIN SELECT count(*) INTO legal_amount FROM table WHERE :old.TBL_ID = :new.TBL_ID; /* Many more AND clauses here */ IF (legal_am
AFTER INSERT OR UPDATE ON table
FOR EACH ROW
DECLARE
legal_amount INT;
BEGIN
SELECT count(*)
INTO legal_amount
FROM table
WHERE :old.TBL_ID = :new.TBL_ID; /* Many more AND clauses here */
IF (legal_amount = 0) THEN
no_legal_amount_procedure(:new.TBL_ID);
END IF;
ELSE
legal_amount_procedure(:new.TBL_ID);
END IF;
END;
导致ORA-04091错误的是select语句
我们以前解决这个问题的方法是通过执行PRAGMA autonomy_事务,但我需要消除它,因为它会导致其他问题(在自治事务中选择与旧事务中需要的未限制数据=null结果)
我也尝试过学习asktom教程,但没有成功,因为AND子句的数量很大,而且这是一个FOR-EACH-ROW语句。我希望这将是最后的手段
我知道在触发器中执行业务逻辑是不好的。但是,如果无法访问源代码,这是解决此问题的唯一方法。使用存储过程包装整个插入,而不是触发器。这是仅用于插入的示例:
CREATE OR REPLACE PROCEDURE insert_table (in_tbl_id INTEGER, ...[other attrs])
IS
v_legal_amount INTEGER;
BEGIN
SELECT count(*)
INTO v_legal_amount
FROM table
WHERE tbl_id = in_tbl_id
/* Many more AND clauses here */;
INSERT INTO table VALUES (tbl_id, ...);
IF (v_legal_amount = 0) THEN
no_legal_amount_procedure (in_tbl_id);
ELSE
legal_amount_procedure (in_tbl_id);
END IF;
END;
使用的程序是什么
no\u legal\u amount\u程序
和legal\u amount\u程序
?选择count(*)…
是否也会触碰已修改的行?在插入后的触发器中使用:old
和:new
。难道不应该有一些条件,比如“如果更新,那么。。。如果插入,则…。这只是一个简化的示例,可能不是100%正确的语法。是,有一个IF更新THEN语句。这两个法定金额程序实际上是一个基于两种不同标准的文件转换程序。这些程序是否可能修改文件的参数?它们是否定义为IN
IN OUT
或IN OUT NOCOPY
?这似乎没有意义:其中:old.TBL_ID=:new.TBL_ID
,因为它本质上意味着“如果我没有更新TBL_ID”。您的意思是其中TBL_ID=:new.TBL_ID
?如果必须在触发器中查询同一个表,请尝试复合触发器。但是查询同一个表不是个好主意。。。