2009-06-08 94 views
6

我们即将运行并行测试,以将旧版系统与新版本进行比较。我们有一个存储遗留系统数据的Oracle数据库表A和一个存储新系统数据的等效表B,所以在测试期间数据库是非规范化的。 (另外,遗留系统和表A是固定的 - 不允许更改)在Oracle中保持表的同步

我想要做的就是让A上不经常的DML操作传播到B,反之亦然。我从一对触发器开始执行此操作,但触发了一个显而易见的问题,即触发器运行时,表格会发生变化,并引发异常。

有没有处理这个问题的标准方法?我读过关于使用DBMS_SCHEDULER是否是要走的路不同的报告...

感谢,

安迪

更新: 我已经结束了chickening出了整个的问题并确保更新A的所有存储过程也更新B,反之亦然。

我标志着Quassnoi的答案接受,因为我按照他的建议,如果面临着在未来同样的问题。

我已经标记了JosephStyon的答案,因为我简单地通过在表A和B上添加两个插入/更新语句级触发器,然后使用A或B作为主表进行合并,这取决于哪个触发器运行(虽然首先我检查了目标表将被合并更改,如果没有提前出现)。

+0

@Andy:如果你的遗留应用程序使用存储过程来更新表,那么为了上帝的缘故,你只需把你的逻辑放入过程中,因为它应该是这样。我的建议只适用于发布DML语句的较差的应用程序(而不是调用过程)来更新数据。 – Quassnoi 2009-06-08 19:49:26

回答

3

我想创建AB作为享有一个规范化(或反规范化)表,并创建了一个INSTEAD OF触发了这些观点来处理DML操作。

如果查询此事的计划,这是更好地保持表的两个副本:A_underlyingB_underlying,创造就像这样的观点:

CREATE VIEW A 
AS 
SELECT * 
FROM A_underlying 

CREATE VIEW B 
AS 
SELECT * 
FROM B_underlying 

谓词将被推入的意见,并查询计划对于实际的表格和视图将是相同的。

INSTEAD OF触发两个视图,你应该把数据放入两个基础表。

+0

这实际上是一个非常好的想法。遗憾的是,遗留应用程序和数据库模式已修复。我已经更新了这个问题来反映这一点。谢谢。 – Andy 2009-06-08 15:21:15

+0

数据库模式将与外界保持一致。您甚至可以在另一个模式中创建基础表。通过创建触发器,您不仅可以通过在基础表上创建视图来更改模式。 – Quassnoi 2009-06-08 15:30:54

+0

是真的。更具体地说:我可以在不影响遗留系统的情况下添加触发器。如果我想创建一个单一的统一表AB的视图,我不得不修改遗留应用程序,以利用它的视图。 – Andy 2009-06-08 15:38:18

1

把下面三个语句在存储过程中,则经常你喜欢运行它作为计划的作业:

--Assume that "A" is a master, and "B" needs to be synched 

--If no match in "A", delete from "B" 
DELETE FROM B 
WHERE NOT EXISTS(
       SELECT * 
       FROM A 
       WHERE A.PRIMARY_KEY = B.PRIMARY_KEY 
       ); 

--If there is a match, but they are different, then update "B" 
update 
    (
    select 
    a.field1 as new_value1 
    ,b.field1 as old_value1 
    ,a.field2 as new_value2 
    ,b.field2 as old_value2 
    ,.... 
    ,a.fieldN as new_valueN 
    ,b.fieldN as old_valueN 
    from 
    a 
    ,b 
where a.primary_key = b.primary_key 
) 
set 
    old_value1 = new_value1 
,old_value2 = new_value2 
,.... 
,old_valueN = new_valueN; 


--if the record is new to "A", then insert it into "B" 
INSERT INTO B 
SELECT * 
FROM A 
WHERE NOT EXISTS(
       SELECT * 
       FROM B 
       WHERE B.PRIMARY_KEY = A.PRIMARY_KEY 
       ); 
1

Oracle 10g及以上的已经实现变更通知作为异步进程。它是自动的,包含在Oracle 10g及更高版本的服务器安装中。

你可以看到here的一些信息。