问题是这样的我建了个表stu(no number,name varchar2(15),adistance number,update_times integer);
表内容如下:
NO NAME ADISTANCE UPDATE_TIMES
---------- --------------- ---------- ------------
10001 sfdf 450 0
10002 Raxxer 475 0
10003 CrystalMM 600 0
10006 Magina 450 0
10004 SandKing 420 0
10005 SkeletonKing 420 0
10009 Flypig 650 0
我就是想写个触发器实现,当我更新修改表中name的时候,对应的update_times会自动加1,例如当我
update stu set name='Terrorblade' where no=10001;后在触发器里实现对update_times自动加1;
我写的触发器是这样的如下:
create or replace trigger au_stu_trg
after update of name on stu
for each row
begin
update stu set adistance=+1
where name=:old.name;
end;
/但我update后:
SQL> update stu set name='Terrorblade' where no=10001;
update stu set name='Terrorblade' where no=10001
*
第 1 行出现错误:
ORA-04091: 表 SYSTEM.STU 发生了变化, 触发器/函数不能读它
ORA-06512: 在 "SYSTEM.AU_TR_GTT", line 2
ORA-04088: 触发器 'SYSTEM.AU_TR_GTT' 执行过程中出错
ORA-06512: 在 "SYSTEM.BU_TR_STU", line 2
ORA-04088: 触发器 'SYSTEM.BU_TR_STU' 执行过程中出错到网上看说是触发器不能对它本身的表操作,就是说如果你在表A上建了触发器,那么该触发器就不能针对表A再操作了,我也搞不懂到底是不是这样,还望哪位能给个明确答复!!抱着试试看的想法我又用了下面的方法:
临时表+2个触发器:
临时表gtt(no number)用来暂时存储stu表中name更新行的no,
临时表:create global temporary table gtt(name varchar2(15)) on commit delete rows;
当更新stu表name时触发器bu_tr_stu实现向gtt中暂存更新行的no
create or replace trigger bu_tr_stu
before update of name on stu
for each row
begin
insert into gtt select no from stu where name=:new.name;
end;
/
下面又创建了触发器 au_tr_gtt,当gtt里有no插入的时候实现对stu表的update_times加1
create or replace trigger au_tr_gtt
after insert on gtt
for each row
begin
update stu set adistance=+1 where
no in (select no from gtt);
end;
/运行后还是报错,我要崩溃了,到底该怎么写啊!
表内容如下:
NO NAME ADISTANCE UPDATE_TIMES
---------- --------------- ---------- ------------
10001 sfdf 450 0
10002 Raxxer 475 0
10003 CrystalMM 600 0
10006 Magina 450 0
10004 SandKing 420 0
10005 SkeletonKing 420 0
10009 Flypig 650 0
我就是想写个触发器实现,当我更新修改表中name的时候,对应的update_times会自动加1,例如当我
update stu set name='Terrorblade' where no=10001;后在触发器里实现对update_times自动加1;
我写的触发器是这样的如下:
create or replace trigger au_stu_trg
after update of name on stu
for each row
begin
update stu set adistance=+1
where name=:old.name;
end;
/但我update后:
SQL> update stu set name='Terrorblade' where no=10001;
update stu set name='Terrorblade' where no=10001
*
第 1 行出现错误:
ORA-04091: 表 SYSTEM.STU 发生了变化, 触发器/函数不能读它
ORA-06512: 在 "SYSTEM.AU_TR_GTT", line 2
ORA-04088: 触发器 'SYSTEM.AU_TR_GTT' 执行过程中出错
ORA-06512: 在 "SYSTEM.BU_TR_STU", line 2
ORA-04088: 触发器 'SYSTEM.BU_TR_STU' 执行过程中出错到网上看说是触发器不能对它本身的表操作,就是说如果你在表A上建了触发器,那么该触发器就不能针对表A再操作了,我也搞不懂到底是不是这样,还望哪位能给个明确答复!!抱着试试看的想法我又用了下面的方法:
临时表+2个触发器:
临时表gtt(no number)用来暂时存储stu表中name更新行的no,
临时表:create global temporary table gtt(name varchar2(15)) on commit delete rows;
当更新stu表name时触发器bu_tr_stu实现向gtt中暂存更新行的no
create or replace trigger bu_tr_stu
before update of name on stu
for each row
begin
insert into gtt select no from stu where name=:new.name;
end;
/
下面又创建了触发器 au_tr_gtt,当gtt里有no插入的时候实现对stu表的update_times加1
create or replace trigger au_tr_gtt
after insert on gtt
for each row
begin
update stu set adistance=+1 where
no in (select no from gtt);
end;
/运行后还是报错,我要崩溃了,到底该怎么写啊!
最关键的就是触发器不能对本表做update,
另外必须是before才能对new表修改,换成after就会报错,无法修改。
最后是赋值的时候=前面要加冒号是必须的。
记着这点下面的就好写了,既然不能用update来指定哪一行update_tims实现自动加,
那就考虑最简单最基本的最原始的算法,只要是同一字段在old和new表里不一样的就表示它要被update了,
就前后做个比较,if。。then语句简单搞定!
create or replace trigger update_fre
before update of name on stu
for each row
begin
if :new.name<>:old.name then
:new.update_times:=:old.update_times+1;
end if;
end;
/问题是解决了,还希望各位看看还有没有其他比较巧的方法!