Oracle - 在没有触发器的情况下更新表时出现“表正在变异,触发器/函数可能看不到它”错误

Posted

技术标签:

【中文标题】Oracle - 在没有触发器的情况下更新表时出现“表正在变异,触发器/函数可能看不到它”错误【英文标题】:Oracle - "table is mutating, trigger/function may not see it" error on update a table with no trigger 【发布时间】:2016-10-08 12:36:06 【问题描述】:

我收到此错误:“ORA-04091: table FASHIONRETAILER.Payslips is mutating, trigger/function may not see it”在尝试更新 Payslips 表时打开,该表中没有触发器它。附上屏幕截图,证明桌子上没有触发器。以下是我的更新声明:

UPDATE "Payslips" 
SET "NETPAY" = calculate_net_pay(user_id)
WHERE "PAYSLIPSID" = (
    SELECT "Payslips"."PAYSLIPSID" FROM "Payslips" 
    WHERE "Payslips"."USERID" = user_id AND "Payslips"."Date" = (
        SELECT MAX("Payslips"."Date") FROM "Payslips" WHERE "Payslips"."USERID" = user_id 
        AND "Payslips"."NETPAY" IS NULL));

calculate_net_pay(user_id) 函数和 WHERE 约束中的子查询工作正常。

【问题讨论】:

你的函数是如何实现的?错误消息是说原因可能是一个函数,而不仅仅是一个触发器。 Mutating Table in Oracle 11 caused by a function的可能重复 我对不得不使用一个名为 "Payslips" 的表有一个名为 "Date" 的列的数据模型表示哀悼。 (顺便说一句,你只需要用非标准命名双引号。) 【参考方案1】:

您可以尝试在函数的声明部分使用pragma autonomous_transaction。 我看不出 calculate_net_pay() 函数究竟做了什么。因此,这可能不是您的情况的最佳解决方案,但它应该有效。 有关自治事务的更多信息,请参阅here

【讨论】:

【参考方案2】:

您无法在函数或触发器中查询您正在更新的同一张表 - 您的函数 calculate_net_pay 就是这样做的,它会尝试通过查询您要更新的表 Payslips 来计算用户的净工资。

尝试使用子查询而不是函数。

【讨论】:

【参考方案3】:

这是否解决了问题并做你想做的事?

UPDATE "Payslips"  p
SET "NETPAY" = calculate_net_pay(p.user_id)
WHERE p."Date" = (SELECT MAX(p2."Date")
                  FROM "Payslips" p2
                  WHERE p2."USERID" = p."USERID" AND
                        p2."NETPAY" IS NULL
                 );

【讨论】:

以上是关于Oracle - 在没有触发器的情况下更新表时出现“表正在变异,触发器/函数可能看不到它”错误的主要内容,如果未能解决你的问题,请参考以下文章

在配置触发器时更新表中的列时出现错误

在更新触发之前执行时出现约束冲突错误

运行 Oracle 调度程序时出现错误:ORA-20001:必须从应用程序会话中调用此过程

在更新 cx_oracle 中的表时出现 DatabaseError: ORA-00933: SQL 命令未正确结束

尝试使用触发器以将行插入另一个表时出现语法错误

编译触发器时出现 Oracle 错误 ORA-00922