我们即将进行并排测试,以将遗留系统与新的闪亮版本进行比较。我们有一个Oracle数据库表A,用于存储遗留系统的数据,以及一个等效表B,用于存储新系统的数据,因此在测试期间,数据库是非规范化的。 (此外,遗留系统和表A是固定的 - 不允许更改)
我想要做的是允许A上不频繁的DML操作传播到B,反之亦然。我开始使用一对触发器来执行此操作,但遇到了一个明显的问题,即当触发器运行时,表会发生变异,并抛出异常。
是否有处理此问题的标准方法?我已经阅读了关于是否使用dbms_scheduler的不同报告...
谢谢,
安迪
更新的 我最终摆脱了整个问题并确保更新A的所有存储过程也更新B,反之亦然。
我已将Quassnoi的答案标记为已被接受,因为如果将来遇到同样的问题我会遵循他的建议。
我已经标记了JosephStyon的答案,因为我简单地通过在表A和B上添加两个插入/更新语句级触发器来完成工作,然后使用A或B作为主表执行其合并过程,具体取决于哪个触发器跑了(虽然我首先检查了目标表是否会被合并更改,如果没有,则表示愿意)。
答案 0 :(得分:3)
我将A
和B
创建为单个规范化(或非规范化)表的视图,并在这些视图上创建INSTEAD OF
触发器来处理DML
个操作
如果查询计划很重要,最好保留两个表副本:A_underlying
和B_underlying
并创建视图,如下所示:
CREATE VIEW A
AS
SELECT *
FROM A_underlying
CREATE VIEW B
AS
SELECT *
FROM B_underlying
谓词将被推送到视图中,实际表和视图的查询计划将是相同的。
在两个视图的INSTEAD OF
触发器中,您应该将数据放入两个基础表中。
答案 1 :(得分:1)
你真的是指DDL,而不是DML吗?
使用DML,您可以查看Oracles Multi Master Replication以保持表格同步,或者您也可以为此目的查看工具SymmetricDS。
使用DDL,我所知道的唯一解决方案是Oracle advanced replication。
答案 2 :(得分: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
);
答案 3 :(得分:1)
Oracle 10g及更高版本已将Change Notification实现为异步过程。它是自动的,并且该软件包包含在Oracle 10g及更高版本的服务器安装中。
您可以查看here了解相关信息。