2015-01-13

[MS SQL] MERGE 同步處理兩個資料表

今天研究了一下MS SQL SERVER 2008才新增的MERGE功能,
主要簡化了比對兩個表格差異處時的新增、修改、刪除動作,
以前需要分開撰寫INSERT、UPDATE、DELETE語法,
透過MERGE比對資料,根據設定更新資料!


--刪除測試表格
IF (SELECT OBJECT_ID('tempdb..#Src_Tmp')) IS NOT NULL DROP TABLE #Src_Tmp;
IF (SELECT OBJECT_ID('tempdb..#Tra_Tmp')) IS NOT NULL DROP TABLE #Tra_Tmp;

--建立表A
CREATE TABLE #Src_Tmp 
(    ProdNo VARCHAR(5),
    Qty INT )

--建立表B    
CREATE TABLE #Tra_Tmp 
(    ProdNo VARCHAR(5),
    Qty INT,
    Memo NVARCHAR(MAX) )    

--新增資料
INSERT INTO #Src_Tmp VALUES 
('aa',10),('bb',22),('cc',22),('dd',69)

INSERT INTO #Tra_Tmp VALUES 
('aa',8,NULL),('ab',15,NULL),('bb',10,NULL),('cc',22,NULL)

/*
--查詢各表格
select * from #Src_Tmp
select * from #Tra_Tmp

--合併表格 FULL JOIN
select ProdNo=COALESCE(S.ProdNo,T.ProdNo),
        SQty=S.Qty,TSQty=T.Qty
from #Src_Tmp S 
        FULL JOIN #Tra_Tmp T ON S.ProdNo=T.ProdNo
*/
 
--MERGE
MERGE INTO #Tra_Tmp AS T--TARGET
USING #Src_Tmp AS S--SOURCE
ON (T.ProdNo=S.ProdNo) 
WHEN NOT MATCHED BY TARGET THEN--以SOURCE比對TATGET,新增TARGET缺少的部分
    INSERT (ProdNo,Qty) VALUES (S.ProdNo,S.Qty)
WHEN NOT MATCHED BY SOURCE THEN--以TATGET比對SOURCE,刪除TATGET多餘的部分
    DELETE
WHEN MATCHED AND (S.Qty<>T.Qty) THEN--Qty資料不相符,以SOURCE更新TATGET Qty欄位
    UPDATE SET T.Qty=S.Qty
    
OUTPUT $action, inserted.*, deleted.*;--輸出inserted、deleted內容

下面截圖顯示資料變動的經過


參考自
MSDN-MERGE (Transact-SQL)
TechNet-使用 MERGE 插入、更新,和刪除資料
SQL Server 2008 T-SQL 新語法介紹 - Merge (效能改善)
張貼留言