MSSQL Merge [Into](一鍵式更新、插入、刪除)

CrazyMo_發表於2015-05-26

引言:

在專案中常常會遇到一個需要對一個表根據條件不同而進行不同的操作,比如說ERP對於員工的管理——錄入員工資訊時,對於新入職的員工就新增一條記錄,在職的老員工電話換號了就更新;已經離職的就刪除等等。其實質就是條件分支,當然我們可以用if else if else 這樣的語句來實現:

if(條件1) 
    update 語句 
else if(條件2)
    insert 語句
else
    delete 語句

但是很明顯這樣效率不高,於是乎在SQL Server 2008的時候微軟增加了一個強大的語句Merge。

Merge 語法解釋:

MERGE 語句是首先對源表和目標表都進行完全表掃描,然後拿源表和目標表檢查,匹配條件,若成立則執行SQL語句1,不成立則執行SQL語句2,最執行SQL語句3。
要注意的是:

  1. Merge操作的只是“操作表”,源表不會有任何變化
  2. Merge的最後結尾必須是以分號結束的,不能忘了分號
  3. 謹記:語法嚴格要求關鍵字之間只能有一個英文空格,不能有多餘的空格
  4. 不一定要把三個操作都寫全,可以根據實際情況
MERGE 
    [ TOP ( expression ) [ PERCENT ] ] 
    [ INTO ] <操作表> --即將做插入、更新、刪除的表
    USING <源表或者資料集或者子查詢> --使用者提供匹配條件來源的集合或者表
    ON <匹配條件> --可以是任意有效的條件組合
    [ WHEN MATCHED [ AND <clause_search_condition> ]--匹配條件成立
        THEN <SQL語句1> ]
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]--匹配條件不成立
        THEN <SQL語句2> ]
    [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]--目標變不存在而源表存在的資料
        THEN <SQL語句3> ] 
;--不要忘記分號

Merge 簡單應用:

1、以另一個表作為源表:

---建立源表
Create Table OriginTable(id Int,caption VarChar(50))
---建立操作表
Create Table TargetTable(id Int,caption VarChar(50))
--插入測試資料
Insert Into dbo.OriginTable(id,caption)VALUES(1,'測試1')
Insert Into dbo.OriginTable(id,caption)VALUES(2,'測試2')
Insert Into dbo.OriginTable(id,caption)VALUES(3,'測試3')
Insert Into dbo.OriginTable(id,caption)VALUES(4,'測試4')
Insert Into dbo.TargetTable(id,caption)VALUES(1,'目標表匹配到了源表則update1')
Insert Into dbo.TargetTable(id,caption)VALUES(3,'目標表匹配到了源表則update2')
Insert Into dbo.TargetTable(id,caption)VALUES(5,'源表裡不存在則delete')
Insert Into dbo.TargetTable(id,caption)VALUES(8,'源表裡不存在則delete')
Select * from OriginTable
Select * from TargetTable

MERGE INTO TargetTable  as T
USING  OriginTable as S 
ON T.id=S.id
WHEN MATCHED --當上面on後的T.id=S.id時,則更新,也可以加上自定義的限制條件 MATCHED AND S.id=2
Then UpDate set T.caption=S.caption
When Not Matched --目標中沒有的id ,在源表中有則插入
Then Insert Values(S.id,S.caption)
When Not Matched By SOURCE --目標表中存在源表中不存在則刪除
Then Delete;--Merge的最後結尾必須是以分號結束的,不能忘了分號 謹記:語法嚴格要求關鍵字之間只能有一個英文空格,不能有多餘的空格

原始資料:這裡寫圖片描述
處理後的TargetTable資料:
這裡寫圖片描述

2、以子查詢作為源表

MERGE INTO TargetTable  as T
USING  (Select top 2 * From TargetTable as a Where a.id<2) as S 
ON T.id=S.id
WHEN MATCHED --當上面on後的T.id=S.id時,則更新,也可以加上自定義的限制條件 MATCHED AND S.id=2
Then UpDate set T.caption='8989898'
When Not Matched --目標中沒有的id ,在源表中有則插入
Then Insert Values(S.id,'99092')
When Not Matched By SOURCE --目標表中存在源表中不存在則刪除
Then Delete;--Merge的最後結尾必須是以分號結束的,不能忘了分號 謹記:語法嚴格要求關鍵字之間只能有一個英文空格,不能有多餘的空格

原始TargetTable資料這裡寫圖片描述
處理後的targetTable資料:這裡寫圖片描述

附Oracle 9i以上Merge的語法:

MERGE INTO [your table-name] [rename your table here] 
USING ( [write your query here] )[rename your query-sql and using just like a table] 
ON ([conditional expression here] AND [...]...) 
WHEN MATHED THEN [here you can execute some update sql or something else ] 
WHEN NOT MATHED THEN [execute something else here ! ] 

相關文章