Arn*_* C. 1 sql oracle plsql database-trigger sql-update
更新我的表时出现此错误
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'
Run Code Online (Sandbox Code Playgroud)
保存对表"Username"的更改时出错."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;
Run Code Online (Sandbox Code Playgroud)
Oracle在此试图告诉您的是:
for each row).例如:
update empproject set startdate = startdate + 100, enddate = enddate + 100;
Run Code Online (Sandbox Code Playgroud)
不应该是一个问题,因为所有的日期范围都会变得相同的天数.但是,在更新第一行并单独查看时,可能存在冲突,因为其他行尚未更改.表中甚至可能只有两行,中间情况会导致重叠的日期范围.然后它会突然取决于Oracle首先为更新选择的两行中的哪一行.在一种情况下,更新将在没有错误的情况下运行,在另一种情况下,它将崩溃.一个不确定的结果,当然是不允许的.
解决方案是在完成更新后检查行.
您可以编写AFTER UPDATE语句触发器(即AFTER UPDATE ON EmpProject没有FOR EACH ROW)并将表的每一行与所有其他行进行比较.在一张大桌子上,这可能相当昂贵.
首选方法是编写复合触发器.此触发器将具有已更改行(或其键)的数组.在触发器AFTER EACH ROW部分中,您将行添加到数组中,并在触发器AFTER STATEMENT部分中检查每个行的重叠范围.
这里描述了Compund触发器:https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#LNPLS2005
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |