我認爲它從target
和source
兩個分支記錄到不同的執行路徑的條件。
下面我給出了一個簡單的數字列表的例子。我使用full 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
)中沒有匹配時,則相應的targ et記錄可以是update
d或delete
d這裏顯然不會有任何源記錄可供參考。
- 當源記錄與目標記錄匹配時(
matched
),則目標記錄也可以是update
d或delete
d,但與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
那麼可以進一步謂詞數據以決定它是否應該是delete
d或update
d。這是通過提供兩個相同的'分支'來完成的,如example d
的MERGE中所示的附加AND
子句。
一旦你完成了MERGE如何工作以及它能做什麼,你應該暫停[閱讀它不做的事](http://www.mssqltips.com/sqlservertip/3074/use-caution -with-SQL服務器合併語句/)。 –
@AaronBertrand,很有意思。但是我們是否應該使用MERGE或UPSERT會造成混淆?你怎麼看? – user960567
對我來說,我會繼續使用傳統的單獨陳述。 MERGE不會增加任何收益並引入潛在風險。 –