1.觸發(fā)器的分類(lèi)
根據(jù)數(shù)據(jù)操作語(yǔ)言來(lái)分,觸發(fā)器分為DML觸發(fā)器和DDL觸發(fā)器,其中,DDL觸發(fā)器是子SQL 2005以來(lái)新引入的。兩者的具體區(qū)別在于:DML觸發(fā)器是為了響應(yīng)DELETE,UPDATE,INSERT語(yǔ)句;DDL觸發(fā)器是為了響應(yīng)CREATE、ALTER、DROP等任何一條修改數(shù)據(jù)庫(kù)結(jié)構(gòu)的語(yǔ)句。今天我們只討論DML觸發(fā)器。
根據(jù)觸發(fā)器的處罰時(shí)間點(diǎn)來(lái)分,觸發(fā)器分為“后觸發(fā)器”、“替代型觸發(fā)器”。后觸發(fā)器是DELETE、UPDATE、INSERT語(yǔ)句運(yùn)行后觸發(fā)的SQL語(yǔ)句;替代性觸發(fā)器是一發(fā)出DELETE、UPDATE或者INSERT語(yǔ)句時(shí),數(shù)據(jù)庫(kù)不執(zhí)行DELETE、UPDATE或者INSERT語(yǔ)句,而直接執(zhí)行觸發(fā)器中的SQL語(yǔ)句;從性能上來(lái)分析,應(yīng)該是替代型觸發(fā)器比較優(yōu)秀。(因?yàn)闊o(wú)論如何,后觸發(fā)型觸發(fā)器都必須執(zhí)行DELETE、UPDATE或者INSERT動(dòng)作,轉(zhuǎn)而執(zhí)行觸發(fā)器中的SQL,而替代型觸發(fā)器直接執(zhí)行SQL語(yǔ)句)。
根據(jù)觸發(fā)器的處罰動(dòng)作來(lái)分,觸發(fā)器可分為INSERT觸發(fā)器、DELETE觸發(fā)器。UPDATE觸發(fā)器可以看作是INSERT觸發(fā)器和DELETE觸發(fā)器的綜合。
最近在做項(xiàng)目的時(shí)候遇到一個(gè)問(wèn)題,就是在查找記錄的時(shí)候輸入關(guān)鍵字找出滿(mǎn)足條件的記錄。一開(kāi)始是每一個(gè)字段一個(gè)關(guān)鍵字,后面感覺(jué)有的查找的時(shí)候會(huì)涉及到6個(gè)甚至更多的字段,感覺(jué)在查找的時(shí)候相當(dāng)困難。網(wǎng)上找了很久,想找到一種能夠不需要指定字段就可以全表搜索的方法,可惜一直沒(méi)找到,最后找到一個(gè)折中的辦法:在每一個(gè)表中定義一個(gè)字段,這個(gè)字段存儲(chǔ)其他所有字段的和,然后查找的時(shí)候就只要匹配這個(gè)字段就行了。
下面是實(shí)現(xiàn)思路:
因?yàn)樵诿織l數(shù)據(jù)插入和修改的時(shí)候需要往這個(gè)字段中插入值或者是更新這個(gè)字段,而如果靠代碼來(lái)控制的話(huà)會(huì)非常麻煩:你必須時(shí)時(shí)刻刻記得在哪里插入數(shù)據(jù)了,又在哪里修改了數(shù)據(jù)。最后想到了觸發(fā)器,直接在數(shù)據(jù)庫(kù)中建立一個(gè)觸發(fā)器。
觸發(fā)器語(yǔ)句如下:
Create trigger [GECOAssets_Trigger]
on [dbo].[GECOAssets] for
insert,update
as
Update GECOAssets Set
SumText=isnull(SourceID,'') +'∩'+isnull(SourceName,'')+'∩'+isnull(StateNow,'')+'∩'+isnull(BuyDepartment,'')+'∩'+isnull(Factory,'')
+'∩'+isnull(SourceType,'')+'∩'+isnull(BackInfo,'')
這樣原本以為已經(jīng)大功告成了,最后測(cè)試的時(shí)候發(fā)現(xiàn),只要插入一條數(shù)據(jù),或者表中的某個(gè)字段的值發(fā)生改變,所有的SumText的值都會(huì)被重新更新或者插入,當(dāng)數(shù)據(jù)量很大的時(shí)候或者數(shù)據(jù)更新插入很頻繁的時(shí)候,勢(shì)必給數(shù)據(jù)庫(kù)造成很大的壓力。
這時(shí)我突然想起了當(dāng)初學(xué)Orace的時(shí)候老師講過(guò)的行級(jí)觸發(fā)器,于是百度、谷歌找了很久,最后得出的結(jié)論是:MS SQLServer不支持行級(jí)觸發(fā)器。這下讓我很受打擊啊,畢竟自己覺(jué)得還不錯(cuò)的方法就這樣被終結(jié)了,心情極度郁悶。不過(guò),不拋棄不放棄是我的座右銘,于是死磕繼續(xù)百度、谷歌,最后發(fā)現(xiàn),在插入和更新數(shù)據(jù)的時(shí)候,會(huì)有一個(gè)表叫做inserted,而這個(gè)表會(huì)存儲(chǔ)你更新時(shí)候的數(shù)據(jù),這樣,我靈光一閃:那這個(gè)表中肯定就會(huì)存儲(chǔ)這條記錄的ID值,只要能取到ID的值,想必就可以指定更新某一條記錄了,也就可以實(shí)現(xiàn)行級(jí)觸發(fā)器的效果了,我抱著試試看的心態(tài)把觸發(fā)器改成了如下:
Alter trigger [GECOAssets_Trigger]
on [dbo].[GECOAssets] for
insert,update
as
Update GECOAssets Set
SumText=isnull(SourceID,'') +'∩'+isnull(SourceName,'')+'∩'+isnull(StateNow,'')+'∩'+isnull(BuyDepartment,'')+'∩'+isnull(Factory,'')
+'∩'+isnull(SourceType,'')+'∩'+isnull(BackInfo,'') where ID in (select ID from inserted)
果不其然,完美地實(shí)現(xiàn)了行級(jí)觸發(fā)器的效果,至此就可以全表不指定字段(當(dāng)然還是需要指定SumText字段的)搜索了,感覺(jué)雖然不是什么完美的解決方案,但是畢竟還是比較理想的實(shí)現(xiàn)了想要的效果。不知道各位有沒(méi)有更好的解決辦法,或者說(shuō)有沒(méi)有第三方的組件來(lái)實(shí)現(xiàn)全表關(guān)鍵字搜索或者更牛的多表聯(lián)合關(guān)鍵字搜索呢?