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