有一个这样的问题。
有一个表A
有 a,b,c,d四个字段,修改一条记录d的值为4
希望把该记录插入相同结构的表B中。并删除A表的这条记录。
希望大神门帮我写一下,万分感谢!!!
触发器

解决方案 »

  1.   

    关注一下这个问题这个会导致  ORA-04091错误建议
    1)类似需求不要依赖触发器
    2)使用业务端进行处理
      

  2.   


    很简单啊,使用自治事务解决。create or replace trigger kgp2
      after update on kgp2  
      for each row
    declare
       pragma autonomous_transaction;  --定义自制失误
    begin
       if :new.name = '5' then
          delete from kgp2 where name =:new.name;
       end if;
       commit; --必须提交,要不然自治事务会回滚
    end kgp2;
      

  3.   


    自治事务?INSERT INTO KGP2 的时候,你表中的数据尚未提交,所以自治事务中是没法查询当前尚未插入的数据的。INSERT的顺序如下:1)INSERT 一条数据 到KGP2表中,但是事务尚未结束,所以,未真正写入数据库。
    2)触发器生效,删除表中的数据,其中where name =:new.name; 查询的是之前表中的数据
    3)自治事务提交
    4)外部的INSERT事务提交,将刚刚INSERT的数据插入到数据库中。
    验证:
    /*create table FOO
    (
      A NUMBER(10),
      B NUMBER(10),
      C NUMBER(10),
      D NUMBER(10)
    )
    ;*/
    --TRUNCATE TABLE FOO;
    --CREATE TABLE BAR(MSG VARCHAR2(200));CREATE OR REPLACE TRIGGER tri_foo
    AFTER INSERT OR UPDATE ON foo
    FOR EACH ROW
    DECLARE
      PRAGMA AUTONOMOUS_TRANSACTION;
      N_NUM NUMBER(5);
    BEGIN
      IF MOD(TRUNC(:NEW.D),2) =0 THEN
          DELETE FROM FOO WHERE FOO.D = :NEW.D;
          SELECT COUNT(1) INTO N_NUM FROM FOO;
          INSERT INTO BAR VALUES (N_NUM);
      END IF;
      COMMIT;
    END;ChenZw> INSERT INTO FOO VALUES(1,1,1,2);
    已创建 1 行。
    ChenZw> COMMIT;
    提交完成。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
    已选择 1 行。
    ChenZw> INSERT INTO FOO VALUES(2,2,2,4);
    已创建 1 行。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
             2          2          2          4
    已选择2行。
    ChenZw> COMMIT;
    提交完成。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
             2          2          2          4
    已选择2行。
    ChenZw> INSERT INTO FOO VALUES(3,3,3,4);
    已创建 1 行。
    ChenZw> COMMIT;
    提交完成。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
             3          3          3          4
    已选择2行。
    ChenZw>
    数据没有按照预想的执行吧?
      

  4.   


    赞同。
    如果必须用oracle来做,那么建议将整个过程写成一个存储过程,不建议使用触发器
      

  5.   


    自治事务?INSERT INTO KGP2 的时候,你表中的数据尚未提交,所以自治事务中是没法查询当前尚未插入的数据的。INSERT的顺序如下:1)INSERT 一条数据 到KGP2表中,但是事务尚未结束,所以,未真正写入数据库。
    2)触发器生效,删除表中的数据,其中where name =:new.name; 查询的是之前表中的数据
    3)自治事务提交
    4)外部的INSERT事务提交,将刚刚INSERT的数据插入到数据库中。
    验证:
    /*create table FOO
    (
      A NUMBER(10),
      B NUMBER(10),
      C NUMBER(10),
      D NUMBER(10)
    )
    ;*/
    --TRUNCATE TABLE FOO;
    --CREATE TABLE BAR(MSG VARCHAR2(200));CREATE OR REPLACE TRIGGER tri_foo
    AFTER INSERT OR UPDATE ON foo
    FOR EACH ROW
    DECLARE
      PRAGMA AUTONOMOUS_TRANSACTION;
      N_NUM NUMBER(5);
    BEGIN
      IF MOD(TRUNC(:NEW.D),2) =0 THEN
          DELETE FROM FOO WHERE FOO.D = :NEW.D;
          SELECT COUNT(1) INTO N_NUM FROM FOO;
          INSERT INTO BAR VALUES (N_NUM);
      END IF;
      COMMIT;
    END;ChenZw> INSERT INTO FOO VALUES(1,1,1,2);
    已创建 1 行。
    ChenZw> COMMIT;
    提交完成。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
    已选择 1 行。
    ChenZw> INSERT INTO FOO VALUES(2,2,2,4);
    已创建 1 行。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
             2          2          2          4
    已选择2行。
    ChenZw> COMMIT;
    提交完成。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
             2          2          2          4
    已选择2行。
    ChenZw> INSERT INTO FOO VALUES(3,3,3,4);
    已创建 1 行。
    ChenZw> COMMIT;
    提交完成。
    ChenZw> SELECT * FROM FOO;
             A          B          C          D
    ---------- ---------- ---------- ----------
             1          1          1          2
             3          3          3          4
    已选择2行。
    ChenZw>
    数据没有按照预想的执行吧?
    启用自制事物其实就是用来操作未提交的数据,要不然启用自制事物干嘛啊?
    启用自制事物后,delete from kgp2 where name =:new.name;是可以找到并且删除。
    您可以自己试下。