3

我正在阅读有关 MERGE 的 msdn 主题。http://msdn.microsoft.com/en-us/library/bb510625.aspx

但这对我来说很困惑。假设我有一张桌子,

DECLARE @T Table
(
    ID INt,
    Name VARCHAR(10)
)

我有,

MERGE INTO @T T1
USING (SELECT 4 AS ID) T2 ON (T1.ID = T2.ID)

WHEN MATCHED THEN每次找到匹配时WHEN NOT MATCHED THEN都会执行,每次找不到匹配时都会执行?这是正确的吗?WHEN NOT MATCHED BY SOURCE和怎么样WHEN NOT MATCHED BY Target。请帮我

4

4 回答 4

1

Merge 基本上会合并两个表的数据。如果源表的 ID 字段存在于目标表中,它将执行UPDATE语句 ( WHEN MATCHED THEN)。如果它不存在,它将执行INSERT( WHEN NOT MATCHED BY TARGET)。

WHEN NOT MATCHED BY SOURCE表示目标表中有一行在源表中不存在。这通常表明该行在源系统中已被删除,您必须决定如何处理它。(在跨国系统的情况下,行只是被删除,而如果您正在处理数据仓库,您希望保留数据,但将其标记为“非活动”或类似的东西)。

在获得MERGE声明之前,必须自己编写此逻辑。

于 2013-11-03T16:06:50.060 回答
1

您获取一个源表,并尝试将新记录合并到该源表中。您根据源数据新数据设置要检查的条件。如果条件为真,那么这是一个匹配,当不为真时,这是不匹配的,每个都有它自己的语句。

最常用的(来自我见过/使用过的 sql)当想要决定是通过插入向源添加新数据还是更新现有记录时。例如,产品库存,您可能正在添加新库存或更新现有库存的计数。

这里有一个很好的例子可以遵循https://www.simple-talk.com/sql/learn-sql-server/the-merge-statement-in-sql-server-2008/

于 2013-11-03T16:07:37.237 回答
1

我认为它是将记录从target和分支source到不同的执行路径。

下面我举一个简单的数字列表的例子。我使用 afull join来表示合并并case表示“分支”。

DECLARE @source TABLE ( i INT, c CHAR(1) )
DECLARE @target TABLE ( i INT )

INSERT INTO @source ( i )
VALUES (1), (2), (3), (4), (5)

INSERT INTO @target ( i )
VALUES (1), (2), (3), (6), (7)

SELECT 
    [source] = s.i, 
    [target] = t.i,
    [branch] = CASE WHEN t.i IS NULL THEN 'not matched by target'
                    WHEN s.i IS NULL THEN 'not matched by source'
                    ELSE 'matched' END,
    [possible action] = CASE WHEN t.i IS NULL THEN 'insert into target'
                             WHEN s.i IS NULL THEN 'update target or delete from target'
                             ELSE 'update target or delete from target' END
FROM @source s
FULL JOIN @target t ON t.i = s.i

这会产生以下内容

source      target      branch                 possible action
----------- ----------- ---------------------  -----------------------------------
1           1           matched                update target or delete from target
2           2           matched                update target or delete from target
3           3           matched                update target or delete from target
4           NULL        not matched by target  insert into target
5           NULL        not matched by target  insert into target
NULL        6           not matched by source  update target or delete from target
NULL        7           not matched by source  update target or delete from target

所以

  • 当源记录在目标 ( ) 中没有匹配项时,not matched by target可以将它们insert编辑到目标中
  • 当目标记录在源 ( ) 中没有匹配项时,not matched by source相应的目标记录可以是updated 或deleted 这里显然不会有任何源记录可以引用。
  • 当源记录匹配目标记录 ( matched) 时,目标记录也可以是updated 或deleted,但与not matched by source此处不同的是,您还将拥有来自源的记录。

请注意,对于更新和删除,无需使用联接或以其他方式将源与目标、目标与目标等在“分支”内关联起来,因为这些关系已经得到解决,就好像您正在采取行动一样个人记录。

例如,您可能认为您必须进行更新

 Update t
 Set t.col = s.col
 From target t
 Join source s On s.id = t.id

但这种情况并非如此。

当一条记录已经是matched或者not matched by source之后,人们可以进一步对数据进行谓词来决定它应该是deleted 还是updated。这是通过为 MERGE 中所示的附加子句提供两个相同的“分支”来完成AND的。example d

于 2013-11-03T16:38:35.310 回答
0

后两者应该是显而易见的。如果未找到匹配项,则意味着一个或另一个表没有另一个表所在的行。也就是说,T1 可能有一行,但 T2 中没有对应的行,或者 T2 可能有一行,但 T1 中没有对应的行。T2 是源,T1 是目标,所以当你说NOT MATCHED BY SOURCE你指定在 T2 没有行时发生的动作,并且NOT MATCHED BY TARGET是在 T1 没有行时发生的。

于 2013-11-03T16:01:23.737 回答