Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 触发器计数行给出ORA-04091:表正在变化,触发器/函数可能看不到它_Sql_Oracle_Plsql_Sql Update_Database Trigger - Fatal编程技术网

Sql 触发器计数行给出ORA-04091:表正在变化,触发器/函数可能看不到它

Sql 触发器计数行给出ORA-04091:表正在变化,触发器/函数可能看不到它,sql,oracle,plsql,sql-update,database-trigger,Sql,Oracle,Plsql,Sql Update,Database Trigger,更新表时出现此错误 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正在

更新表时出现此错误

 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:在“用户名.检查重叠日期更新”第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;

Oracle试图告诉您的是:

  • 更新可以跨越多行
  • 但是,触发器会查看单行更新(
    针对每行)
  • 由于多行update语句的单行更新以任意顺序发生,Oracle无法保证触发器中的子查询的结果是一致的、确定的
  • 例如:

    update empproject set startdate = startdate + 100, enddate = enddate + 100;
    
    这应该不是问题,因为所有日期范围的移位天数都相同。但是,当更新第一行并单独查看时,可能会发生冲突,因为其他行尚未更改。表中甚至可能只有两行,中间情况会导致日期范围重叠。然后,它将突然取决于Oracle首先选择两行中的哪一行进行更新。在一种情况下,更新将在没有错误的情况下运行,在另一种情况下,它将崩溃。一个不确定的结果,这当然是不允许的

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

    您可以为每一行编写一个更新后
    语句触发器(即在EmpProject上更新后
    而不使用
    ),并将表中的每一行与所有其他行进行比较。在一张大桌子上,这可能相当昂贵

    首选方法是写入复合触发器。此触发器将为更改的行(或其键)创建一个数组。在触发器的
    每行之后
    部分,您将该行添加到数组中,在触发器的
    AFTER语句之后
    部分,您将检查每一行的重叠范围


    这里描述了计算触发器:

    Oracle试图告诉您的是:

  • 更新可以跨越多行
  • 但是,触发器会查看单行更新(
    针对每行)
  • 由于多行update语句的单行更新以任意顺序发生,Oracle无法保证触发器中的子查询的结果是一致的、确定的
  • 例如:

    update empproject set startdate = startdate + 100, enddate = enddate + 100;
    
    这应该不是问题,因为所有日期范围的移位天数都相同。但是,当更新第一行并单独查看时,可能会发生冲突,因为其他行尚未更改。表中甚至可能只有两行,中间情况会导致日期范围重叠。然后,它将突然取决于Oracle首先选择两行中的哪一行进行更新。在一种情况下,更新将在没有错误的情况下运行,在另一种情况下,它将崩溃。一个不确定的结果,这当然是不允许的

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

    您可以为每一行编写一个更新后
    语句触发器(即在EmpProject上更新后
    而不使用
    ),并将表中的每一行与所有其他行进行比较。在一张大桌子上,这可能相当昂贵

    首选方法是写入复合触发器。此触发器将为更改的行(或其键)创建一个数组。在触发器的
    每行之后
    部分,您将该行添加到数组中,在触发器的
    AFTER语句之后
    部分,您将检查每一行的重叠范围


    这里描述了计算机触发器:

    您在谷歌上搜索过“正在变异,触发器/函数可能看不到它”吗?请浏览此链接。Jeffrey Kemp讨论了可用于实现“非重叠日期约束”的各种选项,
    to_DATE('2016-09-11 00:00:00','YYYY-MM-DD HH24:MI:SS')
    可以写成
    日期'2016-09-11'
    “EMPPROJECT”
    应该写成
    EMPPROJECT
    。你在谷歌上搜索了吗“正在变异,触发器/函数可能看不到它”?浏览此链接。Jeffrey Kemp讨论了可以用来实现“非重叠日期约束”的各种选项,顺便说一句,
    到日期('2016-09-11 00:00:00','YYYY-MM-DD HH24:MI:SS')
    可以写成
    日期'2016-09-11'
    ,以及
    “EMPPROJECT”
    应写成
    empproject