ORA-04091“更新后”触发器错误,如何解决?
Posted
技术标签:
【中文标题】ORA-04091“更新后”触发器错误,如何解决?【英文标题】:ORA-04091 Error on "after update" trigger, how to get around? 【发布时间】:2019-07-27 23:12:08 【问题描述】:我有一个触发器设置为在更新特定列后触发。我想在另一列的特定值更改为另一个特定值后更新特定列的值。
我收到了错误:
ORA-04091: table tableName is mutating, trigger/function may not see it
ORA-06512: at "triggerName", line 14
ORA-04088: error during execution of trigger 'triggerName'
我已将其重写为更新前和更新后,并尝试将逻辑存储在函数中,并使用“pragma automatic_transaction”,但仍然会抛出错误。
BEFORE update of columnName1 ON tableName
FOR EACH ROW
BEGIN
if :new.columnName1 = 3 AND :old.columnName1 = 1 then
update tablename
set columnName2= MOD(sequenceName.NextVal, 5) + 1
where tableName.columnName2 = :old.columnName2;
end if;
END;
/
当我不更新受触发器响应的更新影响的列时,我不明白为什么整个表都被标记为“变异”。当然,如果表中的另一个值发生变化,您应该能够更新表中列的值,还是我在这里疯了?
注意:一次只会影响一个条目。在我的应用程序逻辑中,我更新了数据库中某个人的状态。我希望数据库只对特定的状态变化做一些逻辑,并且我想避免对这里的逻辑使用 API 调用,正如你所看到的,它只是 PLSQL 中的一行逻辑。
谢谢
【问题讨论】:
ORACLE After update trigger: solving ORA-04091 mutating table error的可能重复 @OldProgrammer 你是对的,尽管这个线程有实际的代码。如果你愿意,可以标记为重复 【参考方案1】:也许您真的不想更新表格,而只是更改正在更新的特定行中的值。
如果是这样,请避开 update
并设置值:
BEFORE update of columnName1 ON tableName
FOR EACH ROW
BEGIN
if :new.columnName1 = 3 AND :old.columnName1 = 1 then
:new.columnName2 := MOD(sequenceName.NextVal, 5) + 1 ;
end if;
END;
【讨论】:
我猜你的意思是:new.columnName2 := MOD(...
以上是关于ORA-04091“更新后”触发器错误,如何解决?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 ORA-04091:表正在变异,触发器/函数可能看不到它?
Oracle数据库如何解决ORA-04091触发器/函数不能读它的问题