-- 寫法 1 IF EXISTS (SELECT1FROM table_A WHEREcol = @col) BEGIN UPDATE table_A SET ... WHEREkey = @col END ELSE BEGIN INSERTINTO table_A (col, ...) VALUES (@col, ...) END
-- 寫法 2 INSERT table_A (col, col2) SELECTcol, col2 FROM table_B WHERENOTEXISTS (SELECTcolFROM table_A WHERE table_A.col = table_B.col);
範例
測試環境如下,採用 SQL Server Profiler 監測
1 2
Microsoft SQL Server 2016 (SP1) (KB3182545) - 13.0.4001.0 (X64) Windows 10 Pro 6.3 <X64> (Build 16299)
SET NOCOUNT ON; -- 確認暫存表是否存在,並移除存在的暫存表 IF OBJECT_ID('tempdb..#Merge_Target') IS NOT NULL DROPTABLE#Merge_Target IF OBJECT_ID('tempdb..#Merge_Source') ISNOTNULL DROPtable#Merge_Source
IF OBJECT_ID('tempdb..#Target') ISNOTNULL DROPTABLE#Target IF OBJECT_ID('tempdb..#Source') ISNOTNULL DROPtable#Source
-- 建立百萬筆隨機資料 (merge 目標資料表) WITH Tally (n) AS ( SELECT TOP 1000000 ROW_NUMBER() OVER (ORDERBY (SELECTNULL)) FROM sys.all_columns a CROSSJOIN sys.all_columns b ) INSERTINTO#Merge_Target SELECT2*n, 1+ABS(CHECKSUM(NEWID()))%1000 FROM Tally;
-- 建立百萬筆隨機資料 (merge 資料來源資料表) WITH Tally (n) AS ( SELECT TOP 1000000 ROW_NUMBER() OVER (ORDERBY (SELECTNULL)) FROM sys.all_columns a CROSSJOIN sys.all_columns b ) INSERTINTO#Merge_Source SELECTCASEWHEN n <= 500000THEN2*n-1ELSE2*n END ,1+ABS(CHECKSUM(NEWID()))%1000 FROM Tally; GO
-- 建立百萬筆隨機資料 (insert update 目標資料表) WITH Tally (n) AS ( SELECT TOP 1000000 ROW_NUMBER() OVER (ORDERBY (SELECTNULL)) FROM sys.all_columns a CROSSJOIN sys.all_columns b ) INSERTINTO#Target SELECT2*n, 1+ABS(CHECKSUM(NEWID()))%1000 FROM Tally;
-- 建立百萬筆隨機資料 (insert update 資料來源資料表) WITH Tally (n) AS ( SELECT TOP 1000000 ROW_NUMBER() OVER (ORDERBY (SELECTNULL)) FROM sys.all_columns a CROSSJOIN sys.all_columns b ) INSERTINTO#Source SELECTCASEWHEN n <= 500000THEN2*n-1ELSE2*n END ,1+ABS(CHECKSUM(NEWID()))%1000 FROM Tally; GO
-- MERGE MERGE#Merge_Target t USING#Merge_Source s ON s.ID = t.ID WHENMATCHEDTHEN UPDATESETValue = s.Value WHENNOTMATCHEDTHEN INSERT (ID, Value) VALUES(s.ID, s.Value); GO
-- UPDATE/INSERT BEGINTRANSACTION T1; UPDATE t SETValue = s.Value FROM#Target t JOIN#Source s ON s.ID = t.ID;
INSERTINTO#Target SELECT s.ID, s.Value FROM#Source s LEFTJOIN#Target t ON s.ID = t.ID WHERE t.ID ISNULL; COMMITTRANSACTION T1; GO