寫在前面的話:之前看過(guò)Merge語(yǔ)句,感覺(jué)沒(méi)什么用,完全可以用其他的方式來(lái)替代,最近又看了看Merge語(yǔ)句,確實(shí)挺好用,可以少寫很多代碼,看起來(lái)也很緊湊,當(dāng)然也有別的優(yōu)點(diǎn)。
====正文開(kāi)始=====
SQL Server 2008 引入了Merge關(guān)鍵字,主要是在一條語(yǔ)句里面可以執(zhí)行insert、update、delete操作,以實(shí)現(xiàn)用一個(gè) 源對(duì)象 的數(shù)據(jù)對(duì) 目標(biāo)對(duì)象 數(shù)據(jù)進(jìn)行操作。注意這里的”源對(duì)象“和”目標(biāo)對(duì)象“我用黑色標(biāo)注了,源對(duì)象和目標(biāo)對(duì)象實(shí)際上不僅僅可以是表Table,還可以是臨時(shí)表、視圖、表變量、CTE,同時(shí)”目標(biāo)對(duì)象“還可以是 Select語(yǔ)句 ,說(shuō)這么多其實(shí)想表達(dá)Merge語(yǔ)句可以很靈活的使用,但是我們理解的話,可以把”源對(duì)象“和”目標(biāo)對(duì)象“想象成Table就行了,畢竟臨時(shí)表、視圖、表變量、CTE也都可以想象成Table。
(注意:如果目標(biāo)對(duì)象是視圖的話,那么對(duì)目標(biāo)對(duì)象的操作,如update,實(shí)際上是對(duì)生成視圖的表進(jìn)行操作的)。
好了,看完上面的文字,你可能已經(jīng)看不下去了,之所以寫上面的話,是為了顯得嚴(yán)謹(jǐn)一些,接下來(lái)就用例子來(lái)講解吧,這個(gè)例子不涉及業(yè)務(wù)邏輯,可以專注于理解Merge的用法,至于實(shí)際中什么時(shí)候用,只能自己悟了,好了,開(kāi)始舉例子。
例如有一個(gè)Student_Target表,如下 表一 ,另外一個(gè)Student_Source表,如下 表二 :
執(zhí)行如下SQL語(yǔ)句:
MERGE INTO Student_Target AS st --這里是目標(biāo)表,它將要被源表Merge USING Student_Source AS ss --這里是源表 ON st.Sno = ss.Sno --這里是匹配條件 WHEN MATCHED --When和Then是配套的,當(dāng)st.sno=ss.sno時(shí),用ss.sname更新st.sname,我們看到這里update后面沒(méi)有寫明更新的表,這里更新的是目標(biāo)表 THEN UPDATE SET st.Sname = ss.Sname WHEN NOT MATCHED BY TARGET --目標(biāo)表中不存在,而源表中存在數(shù)據(jù),那么就執(zhí)行insert操作,這里by target可以省略,但是建議加上 THEN INSERT VALUES ( ss.Sno,ss.Sname) WHEN NOT MATCHED BY SOURCE --當(dāng)目標(biāo)表中存在,而源表中不存在數(shù)據(jù),那么就執(zhí)行delete操作,這里使用了by source THEN DELETE ;
上面SQL語(yǔ)句的意思可以看后面的注釋,這里再做一簡(jiǎn)要說(shuō)明:對(duì)于表一,sno=1的一行和表二sno=1的匹配,所以表一中該行被更新;表一中sno=2,3在表二中不存在,因此delete,表二中sno=4但是在表一中不存在,因此insert,最后結(jié)果如下:
我們看到上面的結(jié)果和表二的內(nèi)容是一樣的,其實(shí)你再分析一下上面的SQL語(yǔ)句,邏輯就是把表二的內(nèi)容弄進(jìn)表一,表一中和表二中不一致的數(shù)據(jù)刪除,似乎我們上面的Merge語(yǔ)句顯得很多余。這里想再說(shuō)明幾點(diǎn):
(1)我們When matched、When not matched by target、when not matched by source都寫上了,其實(shí)是可選的,我們可以根據(jù)自己的需求只使用其中的部分。
(2)前面是Merge into Student_Target as st,其實(shí)可以增加top(n)來(lái)對(duì)特定數(shù)量的行進(jìn)行操作。執(zhí)行如下SQL:?
MERGE TOP(2) INTO Student_Target AS st --這里是目標(biāo)表,它將要被源表Merge USING Student_Source AS ss --這里是源表 ON st.Sno = ss.Sno --這里是匹配條件 WHEN MATCHED --When和Then是配套的,當(dāng)st.sno=ss.sno時(shí),用ss.sname更新st.sname,我們看到這里update后面沒(méi)有寫明更新的表,這里更新的是目標(biāo)表 THEN UPDATE SET st.Sname = ss.Sname WHEN NOT MATCHED BY TARGET --目標(biāo)表中不存在,而源表中存在數(shù)據(jù),那么就執(zhí)行insert操作,這里by target可以省略,但是建議加上 THEN INSERT VALUES ( ss.Sno,ss.Sname) WHEN NOT MATCHED BY SOURCE --當(dāng)目標(biāo)表中存在,而源表中不存在數(shù)據(jù),那么就執(zhí)行delete操作,這里使用了by source THEN DELETE ;
? 最后結(jié)果如下:
所以,增加了top(2),那么目標(biāo)表可以被操作的行只能是2條,上面的update操作一條,insert操作一條,達(dá)到2條,因此后面的delete就不影響了。因此, 對(duì)于top(n)應(yīng)該能夠正確的理解。 ?
(3)前面when matched 其實(shí)還可以配合其他條件一起操作,例如when matched 可以修改為when matched and ss.sno=1或者when matched and st.sno=1;對(duì)于when not matched, 只能夠使用源列 ,也就是說(shuō),增加and ss.sno=1可以,但是增加and st.sno=1就會(huì)報(bào)錯(cuò)了。
(4)Merge最后一定要以分號(hào)結(jié)尾,表示這個(gè)Merge句子完整了。
前面的操作我們看到默認(rèn)的都是對(duì)Target表的操作,有時(shí)候我們想對(duì)Target表操作后,還能夠針對(duì)特定的條件,對(duì)Source表進(jìn)行操作,這是就可以配合Output子句一起,來(lái)完成我們想要的操作。這里Output字句不單單是針對(duì)merge語(yǔ)句的,對(duì)于insert、update、delete等操作也可以用的,所以具體的可以再去單獨(dú)研究研究output子句。
至此,本文也該告一段落,如何使用Merge語(yǔ)句應(yīng)該也沒(méi)有問(wèn)題。可是心中仍然有一個(gè)結(jié),正如上篇文章所寫的: 如何理解group by和聚合函數(shù) 中對(duì)group by和聚合函數(shù)的認(rèn)識(shí)一樣,雖然用起來(lái)不成問(wèn)題,但是總是希望能夠找到一個(gè)天馬行空的想法,能夠換個(gè)角度去認(rèn)識(shí)。比如為啥基本上都是when matched后面跟update,when not matched by target后面跟insert,when not matched by source 后面跟delete呢?為啥when not matched by target后面不能跟delete?為啥when not matched by source后面不能跟insert呢?當(dāng)然可能還有其他疑問(wèn),目前可以跟join結(jié)合起來(lái)應(yīng)該能夠很好的解釋清楚,可是現(xiàn)在還無(wú)法用很好的文字邏輯去表達(dá)清楚,回頭想好怎么寫了再寫吧,請(qǐng)?jiān)徫矣帧焙紒y想“了。
備注:上面的結(jié)已經(jīng)解開(kāi)了,可以看下一篇博文: 如何理解T-SQL中Merge語(yǔ)句(二)
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
