MERGE同步兩個表, 根據與源表的JOIN 條件,來透過插入、更新和刪除目標表行,達到2張表資料一致。
MERGE 語法:
,
MERGE TOP (value) <target_table> USING <table_source> ON <merge_search_condition> [ WHEN MATCHED [ AND <clause_search_condition> ] THEN <merge_matched> ] [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ] THEN <merge_not_matched> ] [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ] THEN <merge_matched> ] [ <output_clause> ] [ OPTION ( <query_hint> ) ] ;
在SQL中,建立2張表,[dbo].[Target_Data]和[dbo].[Source_Data],也就是將來你Merge的2張表。
IF OBJECT_ID('Target_Data') IS NOT NULL DROP TABLE [dbo].[Target_Data] CREATE TABLE [dbo].[Target_Data] ( [ID] INT PRIMARY KEY NOT NULL, [Column1] NVARCHAR(10) NULL, [Column2] NVARCHAR(10) NULL, [Column3] NVARCHAR(10) NULL, [Column4] NVARCHAR(10) NULL, [Column5] NVARCHAR(10) NULL, [Column6] NVARCHAR(10) NULL, [Column7] NVARCHAR(10) NULL, [Column8] NVARCHAR(10) NULL ) GO IF OBJECT_ID('Source_Data') IS NOT NULL DROP TABLE [dbo].[Source_Data] CREATE TABLE [dbo].[Source_Data] ( [ID] INT PRIMARY KEY NOT NULL, [Column1] NVARCHAR(10) NULL, [Column2] NVARCHAR(10) NULL, [Column3] NVARCHAR(10) NULL, [Column4] NVARCHAR(10) NULL, [Column5] NVARCHAR(10) NULL, [Column6] NVARCHAR(10) NULL, [Column7] NVARCHAR(10) NULL, [Column8] NVARCHAR(10) NULL ) GO
此時,在[dbo].[Source_Data]表中,準備一些臨時資料:
IF NOT EXISTS( --這個判斷,是為了不想新增重複資料。 SELECT TOP 1 1 FROM [dbo].[Source_Data] WHERE [ID] = [ID] AND [Column1] = [Column1] AND [Column2] = [Column2] AND [Column3] = [Column3] AND [Column4] = [Column4] AND [Column5] = [Column5] AND [Column6] = [Column6] AND [Column7] = [Column7] AND [Column8] = [Column8] ) INSERT INTO [dbo].[Source_Data] ([ID],[Column1],[Column2],[Column3],[Column4],[Column5],[Column6],[Column7],[Column8]) VALUES (1,N'A000',N'a000',N'B000',N'b000',N'C000',N'c000',N'D000',N'd000'), (2,N'A001',N'a001',N'B001',N'b001',N'C001',N'c001',N'D001',N'd001'), (3,N'A002',N'a002',N'B002',N'b002',N'C002',N'c002',N'D002',N'd002'), (4,N'A003',N'a003',N'B003',N'b003',N'C003',N'c003',N'D003',N'd003'), (5,N'A004',N'a004',N'B004',N'b004',N'C004',N'c004',N'D004',N'd004'), (6,N'A005',N'a005',N'B005',N'b005',N'C005',N'c005',N'D005',N'd005'), (7,N'A006',N'a006',N'B006',N'b006',N'C006',N'c006',N'D006',N'd006'), (8,N'A007',N'a007',N'B007',N'b007',N'C007',N'c007',N'D007',N'd007') GO
檢視[dbo].[Source_Data]和[dbo].[Target_Data]2張表資料:
接下來,我們把[dbo].[Source_Data]資料同步至Target_Data表中,方法可有2種方案,
方案1,INSERT INTO [dbo].[Target_Data] SELECT ... FROM [dbo].[Source_Data]
方案2,使用Merge。
其中方案1,一次性確保成功,資料量小,整個過程中,伺服器正常執行,網路正常,Target_Data沒有Source_Data資料無任何故障突發生。
IF NOT EXISTS( --這個判斷,是為了不想資料被重複新增。 SELECT TOP 1 1 FROM [dbo].[Target_Data] WHERE [ID] = [ID] --AND --[Column1] = [Column1] AND --[Column2] = [Column2] AND --[Column3] = [Column3] AND --[Column4] = [Column4] AND --[Column5] = [Column5] AND --[Column6] = [Column6] AND --[Column7] = [Column7] AND --[Column8] = [Column8] ) INSERT INTO [dbo].[Target_Data]([ID],[Column1],[Column2],[Column3],[Column4],[Column5],[Column6],[Column7],[Column8]) SELECT [ID],[Column1],[Column2],[Column3],[Column4],[Column5],[Column6],[Column7],[Column8] FROM [dbo].[Source_Data] GO
執行SQL程式碼後,可以看看2張表的資料情況:
根據Select結果來看,說明方案1執行成功。
而方案2,它可以更加實用與靈活,插入、更新和刪除操作。可重複執行,可以單獨某一個欄位。
為了練習方案2,得先做一個動作,執行下面SQL程式碼,清除清除[dbo].[Target_Data]資料。
TRUNCATE TABLE [dbo].[Target_Data] GO
編寫Microsoft sql server MERGE:
MERGE INTO [dbo].[Target_Data] AS TARGET USING [dbo].[Source_Data] AS SOURCE ON TARGET.[ID] = SOURCE.[ID] --基本條件,即是相同。當然在這裡還可以新增其他條件 AND ... WHEN MATCHED THEN UPDATE SET TARGET.[Column1] = SOURCE.[Column1], TARGET.[Column2] = SOURCE.[Column2], TARGET.[Column3] = SOURCE.[Column3], TARGET.[Column4] = SOURCE.[Column4], TARGET.[Column5] = SOURCE.[Column5], TARGET.[Column6] = SOURCE.[Column6], TARGET.[Column7] = SOURCE.[Column7], TARGET.[Column8] = SOURCE.[Column8] WHEN NOT MATCHED BY TARGET THEN INSERT ( [ID], [Column1], [Column2], [Column3], [Column4], [Column5], [Column6], [Column7], [Column8] ) VALUES ( SOURCE.[ID], SOURCE.[Column1], SOURCE.[Column2], SOURCE.[Column3], SOURCE.[Column4], SOURCE.[Column5], SOURCE.[Column6], SOURCE.[Column7], SOURCE.[Column8] ) --WHEN NOT MATCHED BY SOURCE THEN --將TARGE表資料刪除 (注意,這步!把資料刪除了。) -- DELETE ; Go
根據ON條件,如果[dbo].[Target_Data]沒存在,而[dbo].[Source_Data]存在,它會把資料INSERT。
還有,就是更新,它把[dbo].[Source_Data]其它欄位資料更新至[dbo].[Target_Data]表中。此要看你寫的更新語句的寫法了。
執行上面Merge程式碼,2張表資料結果一樣。select 2張表的結果就不帖出來,略過。
現在練習上面程式碼行149和150程式碼,把它由註釋改為正常程式碼,這裡的刪除,它是刪除[dbo].[Target_Data]的資料,是[dbo].[Source_Data]中沒有的資料。
練習,先在[dbo].[Target_Data]新增2筆資料。讓步2張表的資料產生差異。
INSERT INTO [dbo].[Target_Data] ([ID],[Column1],[Column2],[Column3],[Column4],[Column5],[Column6],[Column7],[Column8]) VALUES (888,N'A888',N'a888',N'B888',N'b888',N'C888',N'c888',N'D888',N'd888'), (999,N'A999',N'a999',N'B999',N'b999',N'C999',N'c999',N'D999',N'd999') GO
執行程式碼之後,此時,看看2張表的結果
可以在[dbo].[Target_Data]表中,高亮的2行資料,即是剛剛新增的。
再去執行Merge程式碼,它會把上面2筆資料行刪除。
最終結果,2張表的資料相同。