【问题标题】:Trigger counting rows gives ORA-04091: table is mutating, trigger/function may not see it [duplicate]触发器计数行给出 ORA-04091:表正在变异,触发器/函数可能看不到它[重复]
【发布时间】:2019-03-12 03:01:58
【问题描述】:

更新表格时出现此错误

 UPDATE "Username"."EMPPROJECT" 
 SET ENDDATE = TO_DATE('2016-09-11 00:00:00', 'YYYY-MM-DD HH24:MI:SS') 
 WHERE ROWID = 'AAF+8XAAEAAGBIGAAB'
   AND ORA_ROWSCN = '537035617'

保存对表“用户名”的更改时出错。“EMPPROJECT”:第 8 行:
ORA-04091: 表 Username.EMPPROJECT 正在变异,触发器/函数可能 看不到它 ORA-06512:在“Username.CHECKOVERLAPDATEUPDATE”,第 4 行
ORA-04088: 执行触发器 'Username.CHECKOVERLAPDATEUPDATE' 期间出错

触发器定义如下:

create or replace trigger checkOverlapDateUpdate 
before Update on EmpProject
for each row
declare
    countOfOverlap integer;
begin
    select count(*) 
    into countOfOverlap 
    from EmpProject EP 
    where isOverlapping(:new.startDate, :new.endDate, startDate, endDate) = 1 
      and EP.EmpID = :new.EmpId;

    if countOfOverlap > 0 
    then
        RAISE_APPLICATION_ERROR(-00000, 'Overlapping Insertion Dates');
        rollback;
    end if;
end;

【问题讨论】:

  • 你在谷歌上搜索过“正在变异,触发器/函数可能看不到它”吗?
  • 通过这个链接。 Jeffrey Kemp 讨论了可用于实现“非重叠日期约束”jeffkemponoracle.com/2012/08/non-overlapping-dates-constraint 的各种选项
  • 对了,TO_DATE('2016-09-11 00:00:00', 'YYYY-MM-DD HH24:MI:SS')可以写成date '2016-09-11'"EMPPROJECT"应该写成empproject

标签: sql oracle plsql sql-update database-trigger


【解决方案1】:

Oracle 在这里试图告诉您的是:

  1. 一个更新可以跨越多行。
  2. 但是,您的触发器会查看单行更新 (for each row)。
  3. 由于多行更新语句的单行更新以任意顺序发生,Oracle 无法保证与触发器中的子查询一致、确定的结果。

例如:

update empproject set startdate = startdate + 100, enddate = enddate + 100;

应该不是问题,因为所有日期范围都得到相同的天数。但是,在更新第一行时,单独看这个,可能会发生冲突,因为其他行还没有改变。甚至可能仅在表中存在两行,中间情况会导致日期范围重叠。然后它会突然取决于 Oracle 为更新首先选择的两行中的哪一行。在一种情况下,更新运行时不会出错,在另一种情况下,它会崩溃。一个不确定的结果,这当然是不允许的。

解决方案是在完成更新后检查行。

您可以编写一个AFTER UPDATE 语句触发器(即AFTER UPDATE ON EmpProject 没有FOR EACH ROW)并将表的每一行与所有其他行进行比较。在一张大桌子上,这可能会非常昂贵。

首选方法是编写一个复合触发器。此触发器将有一个用于更改行(或其键)的数组。在触发器的 AFTER EACH ROW 部分中,您需要将该行添加到数组中,在触发器的 AFTER STATEMENT 部分中,您将检查每一行的重叠范围。

此处描述了复合触发器:https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#LNPLS2005

【讨论】:

    猜你喜欢
    • 2022-10-20
    • 2015-06-28
    • 2016-04-29
    • 2010-09-27
    • 2013-11-24
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多