MERGE
一連のレコードをテーブルに入れる必要があります。ソース内のUpdateType
列は、ソースにないDELETE
行をターゲットに含めるかどうかを決定します。
UpdateType
等しいD
か... R
D=Delta、R=Refresh
の場合D
、DELETE
ターゲットから一致しない
場合R
は、ターゲットから一致しない場合DELETE
。
WHILE
プロセスがどのように機能するかをよりよく模倣するために、単一のテーブルを反復処理する があります。
MERGEでこれを達成できますか? または、他にどのようなオプションがありますか?
SQL フィドル: http://www.sqlfiddle.com/#!3/9cdfe/16
これが私の例です。唯一の問題は...WHEN NOT MATCHED BY SOURCE
節でソース値を使用できないことです。
DECLARE @BaseTable TABLE
( RN int
,Store int
,UpdateType char(1)
,ItemNumber int
,Name varchar(50)
)
INSERT INTO @BaseTable
SELECT *
FROM
(
SELECT 1 RN, 1 Store, 'D' UpdateType, 1 ItemNumber, 'Wheel' Name
UNION ALL
SELECT 2, 1, 'D', 1, 'Big Wheel'
UNION ALL
SELECT 3, 1, 'D', 2, 'Light'
UNION ALL
SELECT 4, 1, 'R', 1, 'Wide Wheel'
UNION ALL
SELECT 5, 1, 'D', 1, 'Small Wheel'
UNION ALL
SELECT 5, 1, 'D', 4, 'Trunk'
)B
SELECT bt.* FROM @BaseTable bt
DECLARE @Tab TABLE
( Store int
,UpdateType char(1)
,ItemNumber int
,Name varchar(50)
)
DECLARE @count int = 1
--Loop over each row to mimic how the merge will be called.
WHILE @count <= 5
BEGIN
MERGE INTO @Tab T
USING
(
SELECT bt.RN,
bt.Store,
bt.UpdateType,
bt.ItemNumber,
bt.Name,
tab.Store IsRefresh
FROM @BaseTable bt
LEFT JOIN
( --If ANY previous ITERATION was a 'R' then, all subsequent UpdateType MUST = 'R'
--I'm hoping there is a better way to accomplish this.
SELECT Store
FROM @Tab
WHERE UpdateType = 'R'
GROUP BY Store
HAVING COUNT(Store) > 1
)tab
ON bt.Store = tab.Store
WHERE bt.RN = @count
)S
ON S.Store = T.Store AND S.ItemNumber = T.ItemNumber
WHEN MATCHED THEN
UPDATE
SET T.UpdateType = CASE WHEN S.IsRefresh IS NOT NULL THEN 'R' ELSE S.UpdateType END,
T.Name = S.Name
WHEN NOT MATCHED BY TARGET THEN
INSERT(Store,UpdateType,ItemNumber,Name) VALUES(S.Store,S.UpdateType,S.ItemNumber,S.Name)
--WHEN NOT MATCHED BY SOURCE AND S.UpdateType = 'R' THEN
-- DELETE
;
SET @count = @count + 1
END
SELECT * FROM @Tab
--@Tab Expected Result:
-- 1 'R' 1 'Small Wheel'
-- 1 'R' 4 'Trunk'