如何在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;
 当执行到红色字段时就报错?

解决方案 »

  1.   

    view program sources of error stack? 就是这个错误?
      

  2.   

    晕,这个是提示你是否查看原代码,我是说错误号。比如ORA-XXXXX
    不过我大致明白了,ITEMACTIVITYDETAIL表数据发生变化,你在该表上的触发器里,读取该表。这个应该用自治事务了。
    在declare中加入语句PRAGMA AUTONOMOUS_TRANSACTION;
      

  3.   

    给你个例子,刚测试成功。create or replace trigger trig_test
      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;
      

  4.   

    create or replace trigger trigger_ITEMACTIVITYDETAIL
       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;
    这个触发器实现了粉色部分,但是没有实现红色部分,也就是没有实现我更新的字段?是不是需要俩个事务实现的?
      

  5.   

    LNGACTIVITYDETAILID  是不是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 全部更新。
      

  6.   

    什么当前记录? 把当前insert或者update的ITEMACTIVITYDETAIL的数据insert到ITEMACTIVITYDETAIL_new吗?那你用这个啊: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 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; 
      

  7.   

    为什么不是当前记录?你的粉色部分用的select *,会把表里面的数据都弄过去
      

  8.   

    我 来晚了
    前段时候,刚研究了trigger 还给公司做了个专题讲座
    你这个问题就是对触发表在进行了更新动作,其实这是不行的,Oracle明确规定了的1、Oracle规定,不能对执行触发器的表进行操作,但可以用:new和:old进行操作。2、对于Oracle的行级触发器(for each row),不能对本表做任何操作!包括读写。
       原则:
           在before insert 触发器中,可以实现对本表的访问。
           在after insert 触发器中,不能实现对本表的访问。
           在before/after update/delete触发器中,都不能实现对本表的访问。解决办法:
          suiziguo已经说过了,可以采用Oracle的自治事务处理,也可以用:old和:new关键字来获取变量的值再插入你的表(这个不一定都实用,看情况!)。
      

  9.   

    create or replace trigger trigger_ITEMACTIVITYDETAIL
       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 变化的时候!
      

  10.   

    你的目的是不是,当插入ITEMACTIVITYDETAIL 时,如果ITEMACTIVITYDETAIL_new不存在对应LNGACTIVITYDETAILID的记录时,就把当前ITEMACTIVITYDETAIL 的数据插入,当ITEMACTIVITYDETAIL_new存在对应LNGACTIVITYDETAILID的记录时,就把那两个对应LNGACTIVITYDETAILID的记录加1??
    看了这么久,真不明白你想要干什么。。
      

  11.   

    表的语句是很复杂的:
    如何在oracle9i  作一个触发器,功能是在表A insert或update的时候,将这个表A的insert或update的数据把数据插入表B里并且对这个表B里的俩个字段进行更新:然后把这个更新后表B数据在插入表A里。就这样。
      

  12.   

    主键是不是你这两个字段?看update的时候没有where条件啊。
      

  13.   

    貌似这样会死循环。
    insert a->after insert a调用trigger->做事情->insert a ->after insert a又调trigger->又做事情->insert a->after insert a再调trigger希望我想错了
      

  14.   

    create or replace trigger trig_test 
      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;
      

  15.   

    别急,死循环只是我的猜测,不知道suiziguo兄说的自治事务能不能办到。
    因为我就你在19L说的那个需求做一个简单测试的时候,数据库告诉我资源正忙,也就是出死锁了。
    我仔细想了想,似乎是死循环,所以才在21L那么猜的。如不能用trigger,我的建议还是用一个存储过程来实现这个整个的
    insert a->对b做事情->insert a
    的业务逻辑。
    您觉得呢?
      

  16.   

    crazylaa这位你的猜测是正确的出现了ora-00060 等待资源检测到死锁。也就这个方法不可行的。存储过程没有写过,请教一下高手如何写?
      

  17.   

    对于楼主的描述还不是很清楚
    试试在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
      

  18.   

    试试在ITEMACTIVITYDETAIL中加一个字段flag,然后用自治事务