2011-09-15 23 views
0

我有一個ETL過程,對於這個問題的目的,完全在T-SQL中完成。SQL Server合併(排序)和跟蹤更新

在提取階段,目前的流程是:

  1. 截斷我們的「源」表
  2. 插入從ODS表中的所有數據到我們的「源」表

然而,我想要實現執行「增量」加載的能力,其中只包括插入新數據和更新更改的數據。這樣的過程會是這樣的:

  1. 集「檔案」中的「源」表位(現在所有的數據存檔,即不變)
  2. 更新現有從ODS數據爲「源」(集更新的行歸檔位爲0)
  3. 插入從ODS的新數據爲 「源」(與歸檔位0)

我知道在SQL Server 2008+的MERGE聲明。但是,我擔心的是如何正確記錄哪些行實際發生了更改。如果我只是做一個MERGE,我相信找到的每一行都會被標記爲已更改,即使數據本身不變。

除了指定更新謂詞中的每一列之外,是否有任何技巧可以做到這一點?還是有更好的過程來實現我想要做的事情? FWIW,我想避免一個涉及SSIS的解決方案,如果可能的話由於我無法控制的原因。

回答

2

在過去,我在ODS表上實施了一個「操作」標誌,並使用MERGE來確定源和ODS之間是否有任何變化。這需要來自源的唯一密鑰和時間戳。如果你沒有時間戳,你可以想象使用校驗和或類似的東西,但這些都是他們自己的問題。我將源中具有較新時間戳的匹配記錄標記爲「U」,源中不在ODS中的記錄爲「I」,並將ODS中不在源中的記錄標記爲「D」。然後我開始在ODS和目標表之間執行合併的獨立程序。這種方法工作得非常好,因爲每天只需要處理3-4千萬個記錄集中的變化。

1

您可以測試,也許改變了列的條件:

MERGE TableA 
USING TableB 
ON TableA.Id = TableB.Id 
WHEN MATCHED AND (TableA.Column1 != TableB.Column1 OR TableA.Column2 != TableB.Column2 OR ....) 
    UPDATE SET TableA.Column1 = TableB.Column1, 
       TableA.Column2 = TableB.Column2 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT VALUES (TableB.Id, TableB.Column1, TableB.Column2, ....); 

在任何情況下,你必須更加小心空列。