在oracle中为两个链接数据库编写触发器的最佳方法是什么

时间:2015-01-06 16:57:25

标签: database oracle triggers

如果要更新目标数据库中的表,同时注意源数据库表中的更改,则编写数据库触发器的最佳方法是什么。

例如:如果我有source-database.source-table和target-database.target-table。我想在source-database.source-table中进行更改时在target-database.target-table中插入一个条目。我可以写这样的东西。

方法1:在目标数据库上写入触发器:

create or replace trigger "target-database"."target-trigger"
after update on source-database.source-table@source-dblink
for each row
where (:new.some-col <> :old.some-col)
begin
insert into target-database.target-table ("col1","col2","col3")
values
("value1","value2","value3")
end;

方法2:在源数据库上写入触发器

create or replace trigger "source-database"."source-trigger"
after update on source-database.source-table
for each row
where (:new.some-col <> :old.some-col)
begin
insert into target-database.target-table@target-dblink ("col1","col2","col3")
values
("value1","value2","value3")
end;    

2 个答案:

答案 0 :(得分:3)

如果要创建实现复制的触发器,则需要在源数据库上存在触发器。在目标数据库上创建触发器在语法上无效。如果您确实在源数据库上创建了触发器,则需要使用数据库链接来引用目标表,在ON <<table name>>子句中不会有数据库链接。

但是,你真的,真的不想使用触发器来实现复制。 Oracle提供了大量工具来实现复制 - 物化视图,Streams,Golden Gate等。您真的非常希望使用其中一种解决方案。

  • 如果使用触发器复制数据,则会显着降低系统的可用性。只有远程数据库启动并运行且两者之间的网络链接已启动时,才能成功对源表执行此事务。这迫使两个系统紧密耦合 - 你不能在不影响另一个的情况下关闭一个站点进行维护。
  • 如果使用触发器复制数据,则会显着影响系统的性能。针对源表的事务现在必须涉及与远程数据库的两阶段提交。这将涉及多个网络往返,并且通常会相当缓慢(与本地交易相比肯定很慢)。
另一方面,真正的复制解决方案将异步复制数据,而对事务性能几乎没有影响。如果两个系统都启动,数据将在很短的滞后后复制。如果目标系统不可用,则本地事务仍将成功,并且在目标系统恢复时数据将复制。

答案 1 :(得分:0)

直观地说,我宁愿从源DB开始做类似的事情:

create or replace trigger "source-database"."source-trigger"
after update on source-database.source-table
for each row
where (:new.some-col <> :old.some-col)
begin
    insert into target-database.target-table@target-dblink ("col1","col2","col3")
    values ("value1","value2","value3");
end;   
/ 

在插入之前没有对DB链接的引用,这是更好的恕我直言。