【问题标题】:How to update both the source and the target using MERGE?如何使用 MERGE 更新源和目标?
【发布时间】:2015-07-14 11:27:23
【问题描述】:

我有两个要合并的表。每行包含上次修改的时间。我想合并这些表,以便将最新的值分配给两个表。

这是我要使用的代码,注释掉的是导致我的问题的原因。

-- 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]);

它不起作用有两个原因,

1) 它在语法上看起来不像嵌套在WHEN MATCHED THEN 中的IF 语句。

2)它也不希望我更新源,这是有问题的,因为我想双向同步。如果我切换 trgtsrc 我得到错误:

无法绑定多部分标识符“src.Description”。

我怎样才能做到这一点?我应该放弃MERGE 还是它有能力做我想做的事?

我对 SQL 非常陌生,所以如果有任何地方有问题,请随时纠正我的想法。提前致谢。

【问题讨论】:

  • 这不是 MERGE 的工作方式——它用于在一个语句上更新和插入一个表。不是同时更新两个表。

标签: sql sql-server insert merge


【解决方案1】:

我只需要调用两次合并。我决定只有主数据库可以添加或删除整行。

这对我有用:

-- 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 

【讨论】:

  • 第二个语句也可以只是一个简单的 UPDATE,尽管我可以理解您可能希望使用另一个 MERGE 来保持一致性。
【解决方案2】:

总而言之,SQL Server 只允许您在每个语句中修改(插入、更新或删除)一个表。更新两个表需要两个语句。

【讨论】:

    【解决方案3】:

    正如其他答案和 cmets 中所述,您不能在一个语句中进行双向合并,而必须使用多个 MERGE 语句。事实上你需要四个

    1. 更新ClientDB(包括ON语句中的LastModified比较)
    2. 更新 MasterDB(包括 ON 语句中的 LastModified 比较)
    3. 在记录不存在的地方插入 ClientDB
    4. 在记录不存在的地方插入 MasterDB

    这会破坏 MERGE 语句的使用,您可以使用标准的 UPDATE 和 INSERT 查询。

    注意:您也可能不想要 WHEN NOT MATCHED BY SOURCE THEN DELETE,因为这会导致无法从其他数据库获取新记录。

    【讨论】:

      猜你喜欢
      • 2018-08-05
      • 1970-01-01
      • 2017-11-21
      • 2012-06-03
      • 2019-03-30
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      相关资源
      最近更新 更多