如何在oracle9i 作一个触发器,功能是在表A insert或update的时候,将这个表A的insert或update的数据C插入表B里并且对这个表B里的俩个字段进行更新:
如下是我写的代码请各位高手指点,我在测试时候出现error stack?错误?
create or replace trigger trigger_ITEMACTIVITYDETAIL
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new select * from ITEMACTIVITYDETAIL where LNGACTIVITYDETAILID = :new.LNGACTIVITYDETAILID;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1;
end if;
end;
当执行到红色字段时就报错?
如下是我写的代码请各位高手指点,我在测试时候出现error stack?错误?
create or replace trigger trigger_ITEMACTIVITYDETAIL
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new select * from ITEMACTIVITYDETAIL where LNGACTIVITYDETAILID = :new.LNGACTIVITYDETAILID;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1;
end if;
end;
当执行到红色字段时就报错?
不过我大致明白了,ITEMACTIVITYDETAIL表数据发生变化,你在该表上的触发器里,读取该表。这个应该用自治事务了。
在declare中加入语句PRAGMA AUTONOMOUS_TRANSACTION;
after insert OR UPDATE on t1
for each ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF inserting THEN
INSERT INTO t2 VALUES (:NEW.id,:NEW.NAME,:NEW.age);
COMMIT;
END IF;
end trig_test;
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new select * from ITEMACTIVITYDETAIL where LNGACTIVITYDETAILID = :new.LNGACTIVITYDETAILID;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1;
COMMIT;
end if;
end trigger_ITEMACTIVITYDETAIL;
这个触发器实现了粉色部分,但是没有实现红色部分,也就是没有实现我更新的字段?是不是需要俩个事务实现的?
如果是主键,完全可以这么做:create or replace trigger trigger_ITEMACTIVITYDETAIL
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new(一个个字段名) values( :new.LNGACTIVITYDETAILID,:new.*****);--一个个字段值排过去
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1;
end if;
if updat? then
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1;
end if
end; 如果select *存在多条记录,那么只能用自治事务了。
另外你的update语句没有加where条件,貌似会把ITEMACTIVITYDETAIL_new 全部更新。
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new(一个个字段名) values( :new.LNGACTIVITYDETAILID,:new.*****);--一个个字段值排过去
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1 where ***;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1 where ***;
end if;
if updating then
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1 where ***;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1 where ***;
end if;
end;
前段时候,刚研究了trigger 还给公司做了个专题讲座
你这个问题就是对触发表在进行了更新动作,其实这是不行的,Oracle明确规定了的1、Oracle规定,不能对执行触发器的表进行操作,但可以用:new和:old进行操作。2、对于Oracle的行级触发器(for each row),不能对本表做任何操作!包括读写。
原则:
在before insert 触发器中,可以实现对本表的访问。
在after insert 触发器中,不能实现对本表的访问。
在before/after update/delete触发器中,都不能实现对本表的访问。解决办法:
suiziguo已经说过了,可以采用Oracle的自治事务处理,也可以用:old和:new关键字来获取变量的值再插入你的表(这个不一定都实用,看情况!)。
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new select * from ITEMACTIVITYDETAIL where LNGACTIVITYDETAILID = :new.LNGACTIVITYDETAILID ; update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1 ;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1 ;
COMMIT;
end if;
end trigger_ITEMACTIVITYDETAIL;
现在是我测试的时候没有数据:ITEMACTIVITYDETAIL_new 这个表?当这个表ITEMACTIVITYDETAIL 变化的时候!
看了这么久,真不明白你想要干什么。。
如何在oracle9i 作一个触发器,功能是在表A insert或update的时候,将这个表A的insert或update的数据把数据插入表B里并且对这个表B里的俩个字段进行更新:然后把这个更新后表B数据在插入表A里。就这样。
insert a->after insert a调用trigger->做事情->insert a ->after insert a又调trigger->又做事情->insert a->after insert a再调trigger希望我想错了
after insert OR UPDATE on t1
for each ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF inserting THEN
INSERT INTO t2 VALUES (:NEW.id,:NEW.NAME,:NEW.age);
COMMIT;
END IF;
end trig_test;
因为我就你在19L说的那个需求做一个简单测试的时候,数据库告诉我资源正忙,也就是出死锁了。
我仔细想了想,似乎是死循环,所以才在21L那么猜的。如不能用trigger,我的建议还是用一个存储过程来实现这个整个的
insert a->对b做事情->insert a
的业务逻辑。
您觉得呢?
试试在ITEMACTIVITYDETAIL中加一个字段flag,然后用自治事务
create table ITEMACTIVITYDETAIL(LNGACTIVITYDETAILID number,LNGACTIVITYID number,name varchar2(10),flag number default 0);
create table ITEMACTIVITYDETAIL_new(LNGACTIVITYDETAILID number,LNGACTIVITYID number,name varchar2(10));create or replace trigger trigger_ITEMACTIVITYDETAIL
after insert or update of LNGACTIVITYDETAILID,LNGACTIVITYID on ITEMACTIVITYDETAIL
for each row when (new.flag=0)
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
if inserting
THEN
insert into ITEMACTIVITYDETAIL_new values(:new.LNGACTIVITYDETAILID,:new.LNGACTIVITYID,:new.name);
update ITEMACTIVITYDETAIL_new set LNGACTIVITYDETAILID = LNGACTIVITYDETAILID + 1;
update ITEMACTIVITYDETAIL_new set LNGACTIVITYID = LNGACTIVITYID + 1;
insert into ITEMACTIVITYDETAIL select LNGACTIVITYDETAILID,LNGACTIVITYID,name,1 from ITEMACTIVITYDETAIL_new;
end if;
commit;end;
insert into ITEMACTIVITYDETAIL(LNGACTIVITYDETAILID, LNGACTIVITYID,name)values(1,1,'a');
insert into ITEMACTIVITYDETAIL(LNGACTIVITYDETAILID, LNGACTIVITYID,name) values(2,2,'b');
insert into ITEMACTIVITYDETAIL(LNGACTIVITYDETAILID, LNGACTIVITYID,name) select rownum+2,rownum+2,dbms_random.string('l',3) from dual connect by rownum<10;
select * from ITEMACTIVITYDETAIL;LNGACTIVITYDETAILID LNGACTIVITYID NAME FLAG
1 1 a 0
2 2 a 1
2 2 b 0
3 3 a 1
3 3 b 1
3 3 rvt 0
4 4 a 1
4 4 b 1
4 4 rvt 1
4 4 aco 0
5 5 a 1
5 5 b 1
5 5 rvt 1
5 5 aco 1
5 5 iro 0
6 6 a 1
6 6 b 1
6 6 rvt 1
6 6 aco 1
6 6 iro 1
6 6 xba 0
7 7 a 1
7 7 b 1
7 7 rvt 1
7 7 aco 1
7 7 iro 1
7 7 xba 1
7 7 zbi 0
8 8 a 1
8 8 b 1
8 8 rvt 1
8 8 aco 1
8 8 iro 1
8 8 xba 1
8 8 zbi 1
8 8 ift 0
9 9 a 1
9 9 b 1
9 9 rvt 1
9 9 aco 1
9 9 iro 1
9 9 xba 1
9 9 zbi 1
9 9 ift 1
9 9 ptc 0
10 10 a 1
10 10 b 1
10 10 rvt 1
10 10 aco 1
10 10 iro 1
10 10 xba 1
10 10 zbi 1
10 10 ift 1
10 10 ptc 1
10 10 sfs 0
11 11 a 1
11 11 b 1
11 11 rvt 1
11 11 aco 1
11 11 iro 1
11 11 xba 1
11 11 zbi 1
11 11 ift 1
11 11 ptc 1
11 11 sfs 1
11 11 cpa 0
12 12 a 1
12 12 b 1
12 12 rvt 1
12 12 aco 1
12 12 iro 1
12 12 xba 1
12 12 zbi 1
12 12 ift 1
12 12 ptc 1
12 12 sfs 1
12 12 cpa 1select * from ITEMACTIVITYDETAIL_new;LNGACTIVITYDETAILID LNGACTIVITYID NAME
12 12 a
12 12 b
12 12 rvt
12 12 aco
12 12 iro
12 12 xba
12 12 zbi
12 12 ift
12 12 ptc
12 12 sfs
12 12 cpa