Merge語法搭配Except來同步資料表
我們常常有需求要同步兩張資料表資料,我最常用的方式就是用SQL2008後
支援的Merge語法。今天寫TSQL時一直卡住在想用要用下面兩種方式的哪一
種方式才能讓IO又少且語法又簡潔呢?
[方法一:]
IO較高,但語法較簡潔。不用一堆OR判斷式來判斷是否要做update動作。
即便欄位有NULL值也可比較出兩筆ROW資料是否一致。
MERGE Target AS T
USING Source AS S
ON (T.ID = S.ID)
WHEN NOT MATCHED BY TARGET
THEN INSERT(ID, Name) VALUES(S.ID, S.Name)
WHEN MATCHED AND EXISTS(Select * From Target Where ID=T.ID EXCEPT Select * From Source Where ID=S.ID)
THEN UPDATE SET T.Name = S.Name
WHEN NOT MATCHED BY SOURCE
THEN DELETE
[方法二:]
IO較低速度較快,但語法落落長,要用一堆OR判斷式來判斷是否要做update動作。
如果欄位有NULL值就要再用ISNULL來避開。一旦欄位很多,語法就又臭又長。
MERGE Target AS T
USING Source AS S
ON (T.ID = S.ID)
WHEN NOT MATCHED BY TARGET
THEN INSERT(ID, Name) VALUES(S.ID, S.Name)
WHEN MATCHED AND (ISNULL(T.Name,'')<>ISNULL(S.Name,''))
THEN UPDATE SET T.Name = S.Name
WHEN NOT MATCHED BY SOURCE
THEN DELETE
對於這個問題真的很兩難,語法快的卻又臭又長。而且又有NULL值無法
比對需要再用ISNULL處理。用Except方式可以輕易比對出兩個Row是否
資料一致,但每一筆MATCHED資料要Except一次,IO可是很可觀的。
因此不死心的Google看看有無又快又簡潔的語法。
最後Google到一篇討論文才發現我的EXCEPT用法真的是畫蛇添足,搞得
自己IO那麼高。修正後的語法如下,可以降IO也避開NULL問題及落落長
的OR判斷式。
[方法三:]
MERGE Target AS T
USING Source AS S
ON (T.ID = S.ID)
WHEN NOT MATCHED BY TARGET
THEN INSERT(ID, Name) VALUES(S.ID, S.Name)
WHEN MATCHED AND EXISTS(Select S.* EXCEPT Select T.*)
THEN UPDATE SET T.Name = S.Name
WHEN NOT MATCHED BY SOURCE
THEN DELETE
看到上述語法是不是覺得我 [方法一] 的寫法是畫蛇添足啊!
我是ROCK
rockchang@mails.fju.edu.tw