2009-06-08 37 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的一些信息。