簡單練習Microsoft SQL Server MERGE同步兩個表

Insus.NET發表於2024-10-13

MERGE同步兩個表, 根據與源表的JOIN 條件,來透過插入、更新和刪除目標表行,達到2張表資料一致。

MERGE 語法:

簡單練習Microsoft SQL Server 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> ) ]      
;
Source Code


在SQL中,建立2張表,[dbo].[Target_Data]和[dbo].[Source_Data],也就是將來你Merge的2張表。

簡單練習Microsoft SQL Server MERGE同步兩個表
 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
Source Code

此時,在[dbo].[Source_Data]表中,準備一些臨時資料:

簡單練習Microsoft SQL Server MERGE同步兩個表
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
Source Code


檢視[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資料無任何故障突發生。

簡單練習Microsoft SQL Server MERGE同步兩個表
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
Source Code


執行SQL程式碼後,可以看看2張表的資料情況:

根據Select結果來看,說明方案1執行成功。

而方案2,它可以更加實用與靈活,插入、更新和刪除操作。可重複執行,可以單獨某一個欄位。

為了練習方案2,得先做一個動作,執行下面SQL程式碼,清除清除[dbo].[Target_Data]資料。

簡單練習Microsoft SQL Server MERGE同步兩個表
TRUNCATE TABLE [dbo].[Target_Data]
GO
Source Code

編寫Microsoft sql server MERGE:

簡單練習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
Source Code

根據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張表的資料產生差異。

簡單練習Microsoft SQL Server MERGE同步兩個表
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
Source Code

執行程式碼之後,此時,看看2張表的結果

可以在[dbo].[Target_Data]表中,高亮的2行資料,即是剛剛新增的。
再去執行Merge程式碼,它會把上面2筆資料行刪除。
最終結果,2張表的資料相同。

相關文章