web-dev-qa-db-ja.com

SSISパッケージにマージステートメントを実装する方法は?

update price listというプロセスがあります

毎シーズン(年間4シーズン)、新しいアイテムを販売しており、多くのアイテムには価格の変動があります。また、多くの異なる市場があります(これらは異なる国、つまり米国、フランス、ドイツ、英国です。

次のシーズンに向けて、ライブデータベースの内容でテストデータベースを更新する必要があります。

テーブルはたくさんありますが、そのうちの1つに集中しましょう:dbo.tblBCataloguePriceSetItem

これまでのところ、season\yearでフィルタリングされたすべてのテーブルdbo.tblBCataloguePriceSetItemLIVEからTablebackupsというデータベースにTEST server.にインポートします

これにより、約1,500万行がアクセスされます。このインポートが完了したら、次に 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)このMERGEをパッケージ内に実装するには、SSISツールボックスのどの操作を使用すればよいですか?

enter image description here

2)質問(1)の操作を使用して、パッケージにマージを実装するとします。その内部は何でしょうか?異なるドメインの2つの異なるサーバー間で約1500万行を話します。メモリ内で実行されますか?またはどこ?

3)パフォーマンス上の理由から、Execute SQL TaskControl Flowを使用する方が良いでしょうか?

enter image description here

1

データをステージングテーブルに読み込み、SQL内でMERGEステートメントを使用して、データの実際のマージを実行します。

2番目の質問に回答するには: SSIS内のマージ変換 パッケージを使用する場合、操作はSSISパッケージを実行しているサーバーのメモリを利用します。 SSISがメモリを飽和させ、メモリをさらに必要とするか、OSからワーキングセットを制限するように求められた場合、SSISは BLOBTempStoragePathプロパティまたはDataFlowタスクのBufferTempStoragePathプロパティ のいずれかで定義されているようにデータをディスクにページングし始めます。 。これらのプロパティを空白のままにすると、デフォルトでWindowsのTEMPディレクトリになります。これは、多くの場合C:\ドライブにあり、ディスクをいっぱいにすると、OSの問題を間接的に引き起こす可能性があります。

要するに、BLOBTempStoragePathプロパティとBufferTempStoragePathプロパティを適切に設定しない限り、SSIS内で大きなマージ操作を行わないでください。

3
John Eisbrener