io_works主表
wid isFinish finishDate
1 0 null
2 0 nullio_workdes子表
id wid isok
1 1 0
2 1 0
3 1 1怎么使用触发器实现以下功能:
当子表的isok变为1时,检查其他子记录(根据wid)的isok是不是全部为1,如果为1,则修改主表的isFinish为1,否则不变。create or replace trigger TR_IO_WORKDES_UPDATE
after UPDATE on IO_WORKDES
for each row
declare
begin
UPDATE IO_WORKS
SET ISFINISH='1' ,FINISHDATE=TO_CHAR(SYSDATE,'YYYY-MM-DD')
WHERE WID=:OLD.WID;
--AND NOT exists (SELECT ID FROM IO_WORKDES WHERE WID=:OLD.WID AND ISOK='0')end TR_IO_WORKDES_UPDATE;
我写的这个有变异表问题,谢谢!!
if :NEW.isok = 1 then
UPDATE IO_WORKS
SET ISFINISH='1' ,FINISHDATE=TO_CHAR(SYSDATE,'YYYY-MM-DD')
WHERE WID=:OLD.WID;
elsif :NEW.isok = 0 then
null;
end if;
???
就是说当对应的wid相同时,并且isok全部为1才修改主表?
如果是这样的话,我想像不到利用触发器能够解决的办法。除非在修改主表后,利用修改条件去修改主表。
qiyousyc(沈阳棋友) ( ) 信誉:100 Blog 2007-1-5 15:14:38 得分: 0
当子表的isok变为1时,检查其他子记录(根据wid)的isok是不是全部为1,如果为1
???
就是说当对应的wid相同时,并且isok全部为1才修改主表?
如果是这样的话,我想像不到利用触发器能够解决的办法。除非在修改主表后,利用修改条件去修改主表。
理解正确。在程序中修改害怕不彻底,触发器最好。
create or replace trigger tri_io_works
after update or insert on io_works_son
declare
cursor c is select wid,sum_isok from
(select wid,sum(nvl(isok,0))/count(nvl(isok,0)) as sum_isok from io_works_son group by wid)
where sum_isok =1;
v_wid io_works_son.wid%TYPE;
v_isok io_works_son.isok%TYPE;begin
open c;
loop
fetch c into v_wid,v_isok;
exit when c%notfound;
update io_works set isfinish =1 where wid = v_wid;
end loop;
end;
before/* 或者after*/ UPDATE on IO_WORKDES
for each rowif :new.ISOK <> :old.ISOK then
if :new.ISOK='1' then
if NOT exists (SELECT ID FROM IO_WORKDES
WHERE WID=:OLD.WID AND ISOK='0' AND ID<>:old/* 或者new*/.ID ) then
UPDATE IO_WORKS
...还有保错和变异表问题的话可以用包变量和语句级触发器:
定义一个包变量类型为索引表,也可以用数组
在行级触发器
if :old.ISOK='1' and :new.ISOK ='0' then
widchgs(v_wid)='0';
elseif :old.ISOK='0' and :new.ISOK ='1' then
if not widchgs.EXISTS(v_wid) then
widchgs(v_wid)='1';
end if;
end if;在after语句级触发器
可以循环UPDATE IO_WORKS i := widchgs.FIRST;
WHILE i IS NOT NULL LOOP
...widchgs(i)
i := widchgs.NEXT(i);
END LOOP;
if NOT exists (SELECT ID FROM IO_WORKDES WHERE WID=i AND ISOK='0' ) then
UPDATE IO_WORKS
....