假设A,B服务器,都有同一结构表,需要在A服insert一行后,B服表中也insert一行。
基本思路很简单,在A服上Create DataLink, 建同义词TEST2,Create 一个Trigger,
在insert表时自动复制这一行到同义词(B服)。insert语句在col很多的情况下不好写,我想偷懒。
用 insert into Test2 from select * from Table1 where pk_col=value;但这一语句在trigger里不好使。以下是trigger:
create or replace trigger TRIGGER_ON_INSERT_TB1
  after insert on tb1  
  for each row
  
declare
  -- local variables here
  pragma autonomous_transaction;
begin
  --insert into test02 values (:new.c1,:new.c2);--这个方法太笨
  
  --the copy row syntax, need c1 as a primary key
  insert into test02 select * from tb1 where c1=:new.c1;
  commit;
end TRIGGER_ON_INSERT_TB1;在向A服insert的时候,未报错,但B服没有insert任何数据。如果trigger不使用
自治事务,则报错。

解决方案 »

  1.   

    自治事务是一个独立的进程,在insert本身commit以前,该纪录对自治进程是不可见的,所以select返回空纪录集。如果不使用自治事务,在trigger中不能直接读表本身,因为在tigger执行的时候,Oracle不知道该纪录插入是否成功、是否提交。结论,没办法偷懒,老老实实地罗列列名。
      

  2.   

    一点修正
    在行级trigger中不能直接读表本身,在表级trigger中是可以的。所以有一种用零时表的做法,建立一个transaction level的零时表,写2个triggers.
    行级trigger,每次添加一行记录在零时表中加入主键
    create or replace trigger TRIGGER_ON_INSERT_TB1
      after insert on tb1 
      for each row
    begin
      insert into temp_table (id) values (:new.id);
    end TRIGGER_ON_INSERT_TB1; 表级trigger:复制所有主键存在于零时表中的记录
    create or replace trigger TRIGGER_ON_INSERT_TB1
      after insert on tb1 
    begin
      insert into test02 
      select * from tbl1 
      where id in (select id from temp_table);
    end TRIGGER_ON_INSERT_TB1; 当commit的时候,零时表中的记录自动被晴空。