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

时间:2015-05-04 22:15:20

标签: sql sql-server insert merge

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

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

IF

它有两个原因无效,

1)它在语法上似乎没有嵌套在WHEN MATCHED THEN内的trgt语句。

2)它也不希望我更新源,这是有问题的,因为我想同步两种方式。如果我切换srcMERGE,我会收到错误:

  

多部分标识符" src.Description"无法受约束。

我怎样才能做到这一点?我应该放弃void selection_sort () { int arr[5] = {1,5,2,4,3}, n = 5, // ARRAY LENGTH. ni,nj, // ARRAY LENGTH FOR "FORI" AND "FORJ". i, j, minIndex; __asm { lea esi, arr ;I = 0 (ESI USED AS I). mov eax, n mov ni, eax ;N. fori: mov ebx, esi ;MININDEX = I (EBX USED AS MININDEX). mov edi, esi ;J = I (EDI USED AS J). add edi, 4 ;J = I+1. mov eax, n mov nj, eax ;N. forj: ;IF ( ARR[ J ] < ARR[ MININDEX ] ). mov eax, [ edi ] ;EAX = ARR[ J ]. mov edx, [ ebx ] ;EDX = ARR[ MININDEX ]. cmp eax, edx jae nextj ;IF ( ARR[ J ] >= ARR[ MININDEX ] ). mov ebx, edi ;ELSE: MININDEX = J. nextj: ;FOR ( J = I+1; J < N; J++ ). add edi, 4 ;J++. dec nj ;REVERSE COUNTER. jnz forj ;IF (J < N) JUMP. ;IF ( MININDEX != I ). cmp ebx, esi je nexti ;DON'T EXCHANGE. ;EXCHANGE ARR[ I ] AND ARR[ MININDEX ]. mov eax, [ esi ] ;EAX = ARR[ I ]. mov edx, [ ebx ] ;EDX = ARR[ MININDEX ]. mov [ esi ], edx ;ARR[ I ] = ARR[ MININDEX ]. mov [ ebx ], eax ;ARR[ MININDEX ] = ARR[ I ]. nexti: ;FOR ( I = 0; I < N-1; I++ ). add esi, 4 ;I++. dec ni ;REVERSE COUNTER. cmp ni, 1 ;MUST NOT REACH 0. ja fori ;IF I < (N-1) JUMP. } } 还是有能力做我想做的事情?

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

3 个答案:

答案 0 :(得分:2)

我只需要两次调用merge。我决定只有master数据库才能添加或删除整行。

这对我有用:

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

答案 1 :(得分:1)

长和短是SQL Server只允许您为每个语句修改(插入,更新或删除)一个表。更新两个表将需要两个语句。

答案 2 :(得分:0)

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

  1. 更新ClientDB(包括ON语句中的LastModified比较)
  2. 更新MasterDB(包括ON语句中的LastModified比较)
  3. 插入记录不存在的ClientDB
  4. 插入不存在记录的MasterDB
  5. 这相当违反了MERGE语句的使用,你可以使用标准UPDATE&amp; INSERT查询。

    注意:您可能也不希望使用WHEN NOT MATCHED BY SOURCE THEN DELETE,因为它会阻止从其他数据库获取新记录。