I have a table that looks something like:
AccountID, ItemID 1, 100 1, 200 2, 300
I have a proc that accepts a table value parameter which updates the Items associated with an account. We'll pass something like the following:
AccountID, ItemID 3, 100 3, 200
The proc looks something like:
procedure dbo.MyProc( @Items as dbo.ItemListTVP READONLY ) AS BEGIN MERGE INTO myTable as target USING @Items on (Items.AccountId = target.AccountId) AND (Items.ItemId = target.ItemId) WHEN NOT MATCHED BY TARGET THEN INSERT (AccountId, ItemId) VALUES (Items.AccountId, Items.ItemId) ; END
Based on the passed in data I expect it to add 2 new records to the table, which it does.
What I want is to have a WHEN NOT MATCHED BY SOURCE clause which will remove items for the specified account that aren't matched.
For example, if I pass
AccountID, ItemID 1, 100 1, 400
Then I want it to delete the record having 1, 200; but leave ALL of the others.
If I just do:
WHEN NOT MATCHED BY SOURCE THEN DELETE;
then it will remove all records for accounts not referenced (ie: account ids 2 and 3).
How can I do this?
Thanks,
The MERGE statement basically works as separate INSERT, UPDATE, and DELETE statements all within the same statement. You specify a "Source" record set and a "Target" table and the JOIN condition between the two.
At most, we can specify only two WHEN MATCHED clauses in the MERGE statement. If two WHEN MATCHED clauses are specified, one clause must have an update operation and the other one must use delete operation.
I can think of two obvious ways but both of them involve processing the TVP again.
The first is simply to change the DELETE
condition
WHEN NOT MATCHED BY SOURCE AND target.AccountId IN(SELECT AccountId FROM @Items) THEN DELETE;
The second is to use a CTE to restrict the target
WITH cte as ( SELECT ItemId, AccountId FROM @myTable m WHERE EXISTS (SELECT * FROM @Items i WHERE i.AccountId = m.AccountId) ) MERGE INTO cte as target USING @Items Items ON (Items.AccountId = target.AccountId) AND (Items.ItemId = target.ItemId) WHEN NOT MATCHED BY TARGET THEN INSERT (AccountId, ItemId) VALUES (Items.AccountId, Items.ItemId) WHEN NOT MATCHED BY SOURCE THEN DELETE;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With