私はSSISを初めて使用するので、これについてサポートが必要です。存在し、変更された行を検出する方法を説明する article を見つけました。私が見逃しているのは、変更された行を更新する方法です。変更されたレコードを削除して新しいレコードセットを挿入するのも良い解決策であるという記事をいくつか見つけました。問題は、削除のそのステップ(赤いボックス)を実行する方法がわからないということです。
助言がありますか?
データフロータスク内の行を削除する必要がある場合は、OLE DB Command
変換を使用して、DELETE FROM dbo.Table WHERE ColumnName = ?
のようなDELETEステートメントを記述する必要があります。次に、OLE DBコマンド変換の列マッピングで、疑問符で表されるパラメーターを、前の変換からのデータにマップします。この場合、からのデータはユニオンオール2。
ただし、OLE DBコマンドはすべての行に対して実行され、行が多すぎるとパッケージの速度が低下する可能性があるため、このオプションはお勧めしません。
私はこのようなものをお勧めします:
OLE DB Destinationを使用して、出力をUnion All 2
から一時ステージングテーブル(たとえばdbo.Staging)にリダイレクトします。
最終的な宛先テーブルがdbo.Destinationであると仮定します。これで、ステージングテーブルに、テーブルDestinationから削除する必要のあるすべてのレコードが含まれます。
制御フロータブで、Execute SQL Task
の後にData Flow Task
を配置します。 [SQLの実行タスク]で、SQLステートメントを作成するか、SQLステートメントを呼び出すストアドプロシージャを使用して、ステージングと宛先の間のレコードを結合し、宛先テーブルから一致するすべての行を削除します。
また、データフロータスクの前に別のSQL実行タスクを配置します。このSQL実行タスクでは、ステージングテーブルから行を削除/切り捨てます。
このようなものは、行を削除するために機能する可能性があります。
DELETE D
FROM dbo.Destination D
INNER JOIN dbo.Staging S
ON D.DestinationId = S.StagingId
お役に立てば幸いです。
ser756519回答 に加えて。 ExecuteSQL Deleteステートメントの最後のステップ(4)を削除するレコードが数百万ある場合は、次のようなバッチで実行できます。
WHILE (1=1)
BEGIN
DELETE D
from dbo.Destination D
inner join
(
-- select ids that should be removed from table
SELECT TOP(10000) DestinationId
FROM
(
SELECT
D1.DestinationId,
S.StagingId
from
dbo.Destination as D1
LEFT JOIN
dbo.Staging as S
ON
D1.DestinationId = S.StagingId
) AS G
WHERE
StagingId IS NULL
) as R
on D.DestinationId = R.DestinationId;
IF @@ROWCOUNT < 1 BREAK
-- info message
DECLARE @timestamp VARCHAR(50)
SELECT @timestamp = CAST(getdate() AS VARCHAR)
RAISERROR ('Chunk deleted %s', 10, 1,@timestamp) WITH NOWAIT
END