2013-04-14 220 views
0

我有一個表(Customer_Master_File)需要從平面文件轉儲到文件夾中更新。我有一個運行拿起平面文件,然後導入到一個臨時表(temp_Customer_Master_File)使用SQL合併或更新/插入

我已經無法做的就是這個SSIS包:

在臨時表中的每個記錄,如果Customer_Number存在於主表中,如果不插入臨時表的內容,則更新它。

我正在更新記錄的所有字段,而不是查找單個字段更改。

我試過了SQL合併函數,但是它在源數據中有多條記錄時出錯。

平面文件包含對客戶記錄的更改,並且一次可能有多個更改。我只是想根據需要使用插入或更新來處理每條記錄。

我也嘗試做一個INSERT INTO MASTER_FILE從TEMP_TABLE WHERE CUSTOMER_NUMBER不在MASTER_FILE中,但是當它碰到一個重複的源行時,它也失敗了一個PK錯誤。

回答

3
UPDATE m SET 
    col2 = t.col2, 
    col3 = t.col3 -- etc. - all columns except Customer_Number 
FROM dbo.Master_File AS m 
INNER JOIN 
(
    SELECT 
    Customer_Number, rn = ROW_NUMBER() OVER 
    (
     PARTITION BY Customer_Number ORDER BY [timestamp_column] DESC 
    ), col2, col3, ... etc ... 
    FROM dbo.Temp_Table 
) AS t 
ON m.Customer_Number = t.Customer_Number 
WHERE t.rn = 1; 

INSERT dbo.Master_File(Customer_Number, col2, col3, ...etc...) 
    SELECT Customer_Number, col2, col3, ...etc... 
    FROM 
    (
    SELECT 
     Customer_Number, rn = ROW_NUMBER() OVER 
     (
     PARTITION BY Customer_Number ORDER BY [timestamp_column DESC 
    ), 
     col2, col3, ...etc... 
    FROM dbo.Temp_Table AS t 
    WHERE NOT EXISTS 
    (
     SELECT 1 FROM dbo.Master_File AS m 
     WHERE m.Customer_Number = t.Customer_Number 
    ) 
) AS x WHERE rn = 1; 

這會處理源表中不存在於目標中的多行。我已經對列名稱做了一個假設,您必須對其進行調整。

MERGE可能是誘人的,但也有我從中迴避的幾個原因:

  1. 語法是艱鉅的,很難記住...
  2. you don't get any more concurrency than the above approach unless you intentionally add specific locking hints ...
  3. there are many unresolved bugs with MERGE和可能還有很多還沒有被發現......

I recently published a cautionary tip here as well

+0

謝謝你,這些更新工作完美,插入失敗,由於重複的行。插入時使用哪條記錄並不重要,temp_table中有一個時間戳列,所以最近的記錄會起作用。 – Kerberos42

+0

感謝您使用timestamp專欄進行更新,我沒有嘗試過,但它看起來像會起作用。再次感謝你! – Kerberos42