Reputation: 17946
I have two tables that I want to merge. Each has row contains the last time it was modified. I want to merge the tables such that the newest value is assigned to both tables.
This is the code I want to use, what's commented out is what's causing my problems.
-- synchronize databases
MERGE [ClientDB].[dbo].[Table] trgt
USING [MasterDB].[dbo].[Table] src
ON trgt.ID = src.ID
WHEN MATCHED THEN
-- IF src.LastModified > trgt.LastModified -- if the source is newer
UPDATE SET trgt.[Info] = src.[Info] -- update the target
-- ELSE
-- UPDATE SET src.[Info] = trgt.[Info] -- otherwise update the source
WHEN NOT MATCHED BY SOURCE
THEN DELETE
WHEN NOT MATCHED BY TARGET
THEN INSERT ([Info]) VALUES (src.[Info]);
It doesn't work for two reasons,
1) it doesn't appear to syntactically like the IF
statement nested inside the WHEN MATCHED THEN
.
2) It also doesn't want me to update the source, which is problematic because I want to synchronize both ways. If I switch trgt
and src
I get the error:
The multi-part identifier "src.Description" could not be bound.
How can I accomplish this? Should I abandon MERGE
or does it have the capability to do what I want?
I'm extremely new to SQL so feel free to correct my thinking if it's wrong anywhere. Thanks in advance.
Upvotes: 2
Views: 1952
Reputation: 17946
I just needed to call merge twice. I decided that only the master database could add or remove entire rows.
This worked for me:
-- merge databases
-- update the client from the master
MERGE [ClientDB].[dbo].[table] trgt
using [MasterDB].[dbo].[table] src
ON trgt.id = src.id
WHEN matched AND trgt.lastmodified <= src.lastmodified THEN -- if the master has a row newer than the client
UPDATE SET trgt.[info] = src.[info], ... -- update the client
WHEN NOT matched BY source -- delete any rows added by a client
THEN
DELETE
WHEN NOT matched BY target -- insert any rows added by the master
THEN
INSERT ( [info], ... ) VALUES (src.[info], ... );
-- update the master from the client
MERGE [MasterDB].[dbo].[table] trgt
using [ClientDB].[dbo].[table] src
ON trgt.id = src.id
WHEN matched AND trgt.lastmodified < src.lastmodified THEN -- if the client is newer than the master
UPDATE SET trgt.[info] = src.[info], ... -- update the master
Upvotes: 2
Reputation: 11527
As stated in the other answers and comments, you can't do a two way merge in one statement and will have to use more than one MERGE statement. In fact you would require four
Which rather defeats the use of the MERGE statement and you could use standard UPDATE & INSERT queries.
Note: You also probably don't want the WHEN NOT MATCHED BY SOURCE
THEN DELETE
as that would defeat getting new records from the other database.
Upvotes: 0
Reputation: 40309
The long and short is that SQL Server only lets you modify (insert, update, or delete) one table per statement. Updating two table will require two statements.
Upvotes: 1