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:必须从应用程序会话中调用此过程