Sql-Server

如何在 SSIS 包中實現合併語句?

  • September 21, 2016

我們有一個叫做update price list

每個季節(每年 4 個季節)我們都會出售新商品,並且許多商品的價格都有所不同。我們也有許多不同的市場(這些是不同的國家,即美國、法國、德國、英國

我需要用即將到來的新賽季實時數據庫的內容更新測試數據庫。

我有很多表,但讓我們專注於其中一張:dbo.tblBCataloguePriceSetItem

到目前為止,我將按dbo.tblBCataloguePriceSetItem季節\年份過濾的所有表導入到LIVE名為Tablebackups``TEST server.

這將帶來大約 1500 萬行。導入完成後,我使用 Merge 命令根據下面的腳本實時刷新數據(這是一個大合併)。

USE My_database_in_the_test_server
GO



IF OBJECT_ID( 'tempdb..#ItemChanges') IS NOT NULL DROP TABLE #ItemChanges;

CREATE TABLE #ItemChanges(
 ChangeType         NVARCHAR(10)
,CustomerNum        TINYINT NOT NULL
,NewCustomerName    VARCHAR(25) NULL
,PrevCustomerName   VARCHAR(25) NULL
,NewPlanet          VARCHAR(25) NULL
,PrevPlanet         VARCHAR(25) NULL
,UserName           NVARCHAR(100) NOT NULL
,DateTimeChanged    DateTime NOT NULL);



BEGIN TRANSACTION T1

SET IDENTITY_INSERT dbo.tblBCataloguePriceSetItem  ON;

SELECT @@TRANCOUNT
SELECT XACT_STATE()

MERGE dbo.tblBCataloguePriceSetItem  AS TARGET
USING tablebackups.dbo.tblBCataloguePriceSetItem AS SOURCE
  ON TARGET.lngCataloguePriceSetItemID = SOURCE.lngCataloguePriceSetItemID

WHEN MATCHED

           THEN UPDATE SET 
                  [lngCataloguePriceSetID] = SOURCE.lngCataloguePriceSetID
                 ,[strItemNo] = SOURCE.strItemNo
                 ,[strTier1] = SOURCE.strTier1
                 ,[strTier2] = SOURCE.strTier2
                 ,[strTier3] = SOURCE.strTier3
                 ,[strTier4] = SOURCE.strTier4
                 ,[strTier5] = SOURCE.strTier5
                 ,[strTier6] = SOURCE.strTier6
                 ,[sintNameStructureID] = SOURCE.sintNameStructureID
                 ,[strCurrencyCode] = SOURCE.strCurrencyCode
                 ,[decPrice] = SOURCE.decPrice
                 ,[decWasPrice] = SOURCE.decWasPrice
                 ,[strBCCurrencyCode] = SOURCE.strBCCurrencyCode
                 ,[decBCPrice] = SOURCE.decBCPrice
                 ,[decBCWasPrice] = SOURCE.decBCWasPrice

WHEN NOT MATCHED BY TARGET


            THEN INSERT(   [lngCataloguePriceSetItemID]
                          ,[lngCataloguePriceSetID]
                          ,[strItemNo]
                          ,[strTier1]
                          ,[strTier2]
                          ,[strTier3]
                          ,[strTier4]
                          ,[strTier5]
                          ,[strTier6]
                          ,[sintNameStructureID]
                          ,[strCurrencyCode]
                          ,[decPrice]
                          ,[decWasPrice]
                          ,[strBCCurrencyCode]
                          ,[decBCPrice]
                          ,[decBCWasPrice]
               )
               VALUES( 
                           SOURCE.[lngCataloguePriceSetItemID]
                          ,SOURCE.[lngCataloguePriceSetID]
                          ,SOURCE.[strItemNo]
                          ,SOURCE.[strTier1]
                          ,SOURCE.[strTier2]
                          ,SOURCE.[strTier3]
                          ,SOURCE.[strTier4]
                          ,SOURCE.[strTier5]
                          ,SOURCE.[strTier6]
                          ,SOURCE.[sintNameStructureID]
                          ,SOURCE.[strCurrencyCode]
                          ,SOURCE.[decPrice]
                          ,SOURCE.[decWasPrice]
                          ,SOURCE.[strBCCurrencyCode]
                          ,SOURCE.[decBCPrice]
                          ,SOURCE.[decBCWasPrice]
                       )

WHEN NOT MATCHED BY SOURCE

           THEN DELETE 
--$action specifies a column of type nvarchar(10) 
--in the OUTPUT clause that returns one of three 
--values for each row: 'INSERT', 'UPDATE', or 'DELETE', 
--according to the action that was performed on that row
-------------------------------------
OUTPUT
  $ACTION ChangeType,
  coalesce (inserted.CustomerNum, deleted.CustomerNum) CustomerNum,
  inserted.CustomerName NewCustomerName,
  deleted.CustomerName PrevCustomerName,
  inserted.Planet NewPlanet,
  deleted.Planet PrevPlanet,
  SUSER_SNAME() UserName,
  Getdate () DateTimeChanged
   INTO #ItemChanges
-------------------------------------
;


SELECT @@ROWCOUNT;

SET IDENTITY_INSERT dbo.tblBCataloguePriceSetItem  OFF;

COMMIT TRANSACTION T1 
GO

我正在嘗試將整個事情放入 SSIS 包中,但我有我的擔憂和懷疑。

  1. 我應該使用 SSIS 工具箱中的什麼操作來MERGE在我的包中實現它?

在此處輸入圖像描述

2)假設我確實使用問題(1)的操作在包中實現了合併。它的內部是什麼?我們談論的是不同域中 2 台不同伺服器之間的 1500 萬行。它會在記憶體中執行嗎?還是在哪裡?

Execute SQL Task3)出於性能原因,在中使用 a 會更好Control Flow嗎?

在此處輸入圖像描述

將數據載入到臨時表中,然後使用MERGESQL 中的語句來執行數據的實際合併。

要回答您的第二個問題:如果您在 SSIS 包中使用合併轉換,則該操作將利用執行 SSIS 包的伺服器上的記憶體。如果 SSIS 使記憶體飽和並且需要更多記憶體或者作業系統要求限制其工作集,則 SSIS 將開始將數據分頁到磁碟,如DataFlow 任務中的 BLOBTempStoragePath 或 BufferTempStoragePath 屬性中定義的那樣。如果這些屬性留空,則它們預設為 WindowsTEMP目錄,該目錄通常位於C:\驅動器上,如果您填滿磁碟,可能會間接導致一些作業系統問題。

長話短說,除非您相應地設置BLOBTempStoragePathBufferTempStoragePath屬性,否則不要在 SSIS 中進行大型合併操作。

引用自:https://dba.stackexchange.com/questions/150136