简体   繁体   English

如何使用MERGE更新源和目标?

[英]How to update both the source and the target using MERGE?

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 . 1)在语法上似乎不像WHEN MATCHED THEN内嵌套的IF语句。

2) It also doesn't want me to update the source, which is problematic because I want to synchronize both ways. 2)它也不希望我更新源,这是有问题的,因为我想同时同步两种方式。 If I switch trgt and src I get the error: 如果我切换trgtsrc会收到错误:

The multi-part identifier "src.Description" could not be bound. 不能绑定多部分标识符“ src.Description”。

How can I accomplish this? 我该怎么做? Should I abandon MERGE or does it have the capability to do what I want? 我应该放弃MERGE还是有能力做我想做的事情?

I'm extremely new to SQL so feel free to correct my thinking if it's wrong anywhere. 我对SQL非常陌生,因此如果在任何地方出错,请随时纠正我的想法。 Thanks in advance. 提前致谢。

I just needed to call merge twice. 我只需要调用合并两次。 I decided that only the master database could add or remove entire rows. 我决定只有master数据库可以添加或删除整个行。

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 

The long and short is that SQL Server only lets you modify (insert, update, or delete) one table per statement. 总而言之,SQL Server只允许您修改(插入,更新或删除)每个语句一个表。 Updating two table will require two statements. 更新两个表将需要两个语句。

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. 如其他答案和评论所述,您不能在一个语句中进行两种方式的合并,而将不得不使用多个MERGE语句。 In fact you would require four 实际上,您需要四个

  1. To update ClientDB (including the LastModified comparison in the ON statement) 更新ClientDB(包括ON语句中的LastModified比较)
  2. To update MasterDB (including the LastModified comparison in the ON statement) 更新MasterDB(包括ON语句中的LastModified比较)
  3. To insert ClientDB where the record doesn't exist 在不存在记录的地方插入ClientDB
  4. To insert MasterDB where the record doesn't exist 在不存在记录的地方插入MasterDB

Which rather defeats the use of the MERGE statement and you could use standard UPDATE & INSERT queries. 宁可使用MERGE语句,也可以使用标准的UPDATE&INSERT查询。

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. 注意:您也可能不希望“ WHEN NOT MATCHED BY SOURCE THEN DELETE因为那样会使从另一个数据库获取新记录失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM