Reputation: 41298
I've been using the MERGE operation in SQL Server 2008, but have now come across a similar scenario where I need the same "detection" behaviour (WHEN MATCHED
, WHEN NOT MATCHED BY SOURCE
, WHEN NOT MATCHED BY TARGET
), but want the resulting operations to be on different tables, not the source or the target.
In other words, I have two result-sets, beforeTable
and afterTable
and I want to do something along the lines of:
MERGE afterTable AS dest
USING beforeTable AS source
ON (dest.ID = source.ID)
WHEN MATCHED THEN
--INSERT tblModifiedItems (ID) VALUES (ID)
WHEN NOT MATCHED BY TARGET THEN
--INSERT tblRemovedItems (ID) VALUES (ID)
WHEN NOT MATCHED BY SOURCE THEN
--INSERT tblAddedItems (ID) VALUES (ID)
Presently I do this with three seperate (albeit very simple) queries across the two tables, but the MERGE approach would allow it to be done as a single operation. I just can't see whether it can be used to target different tables than the two under comparison.
Is this possible, and if so how?
[EDIT]
The reason I want to do this is not due to issues around atomicity of the INSERTS into added/removed/modifed (the whole thing is already in a transaction). It is because I want to be able to generate the three sets of data in a single query, or at least a single statement which also makes the intent very clear.
Upvotes: 1
Views: 777
Reputation: 36146
short answer would be: no, you can't. MERGE is an operation between source table and destination table and that's it. But, I suggest an work-around (there is always one). You'll have to write some more code, but it will do the trick.
Do this:
DECLARE @AuxTable table(
id int,
OLD_name varchar(50),
new_name varchar(50)
)
merge table2 as dest
using table1 as src
on (dest.id=src.id)
when not matched by target then
insert (id, name) values (src.id, src.name)
when matched then
UPDATE SET dest.NAME=src.name
when not matched by SOURCE then
DELETE
output inserted.id, DELETED.name, INSERTED.NAME
into @AuxTable
;
select * from @AuxTable
see the "output into @AuxTable"
? That will insert all the modified values by your merge on a temp table. What yo'll have to do is run through this table and build a string to execute the SQL on your other table.
Use this logic:
Upvotes: 2