我們?cè)谶M(jìn)行項(xiàng)目開發(fā)中,經(jīng)常會(huì)遇到多條件模糊查詢的需求。對(duì)此,我們常見的解決方案有兩種:一是在程序端拼接SQL字符串,根據(jù)是否選擇了某個(gè)條件,構(gòu)造相應(yīng)的SQL字符串;二是在數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程中使用動(dòng)態(tài)的SQL語(yǔ)句。其本質(zhì)也是拼接SQL字符串,不過(guò)是從程序端轉(zhuǎn)移到數(shù)據(jù)庫(kù)端而已。
這兩種方式的缺點(diǎn)是顯而易見的:一是當(dāng)多個(gè)條件每個(gè)都可為空時(shí),要使用多個(gè)if語(yǔ)句進(jìn)行判斷;二是拼接的SQL語(yǔ)句容易產(chǎn)生SQL注入漏洞。
最近寫數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程的時(shí)候經(jīng)常使用case when 語(yǔ)句,正好可以用這個(gè)語(yǔ)句解決一下以上問(wèn)題。以SQL中的NorthWind數(shù)據(jù)庫(kù)為例,我要操作的是其中的Employees表,該表中默認(rèn)數(shù)據(jù)如下:
使用如下腳本來(lái)查詢表中數(shù)據(jù):
1 DECLARE @FirstName NVARCHAR(10),
2 @LastName NVARCHAR(20);
3SELECT @FirstName ='', 4 @LastName =''; 5SELECT*6 FROM Employees c
7 WHERE CHARINDEX(
8 (
9CASE10 WHEN @FirstName ='' THEN FirstName11ELSE @FirstName
12END13 ),
14 FirstName
15 ) >016AND CHARINDEX(
17 (CASE WHEN @LastName ='' THEN LastName ELSE @LastName END),18 LastName
19 ) >0執(zhí)行后會(huì)發(fā)現(xiàn)查出的結(jié)果和圖1一樣。
我們把第二行的@FirstName變量賦值為'n'試試,會(huì)把所有FirstName字段中包含字符串'n'的記錄查出來(lái),如下圖:
如果我們?cè)侔训谌械腀LastName變量賦值為'd'試試,結(jié)果會(huì)把所有FirstName字段包含'n'并且LastName字段包含'd'的記錄查出來(lái),如下圖:
通過(guò)以上例子我們可以看到,通過(guò)給兩個(gè)變量傳遞不同的值,就可以根據(jù)多條件進(jìn)行模糊查詢了,如果把上面的語(yǔ)句寫在存儲(chǔ)過(guò)程中,就可以不必再拼接SQL語(yǔ)句了,也不會(huì)出現(xiàn)注入式問(wèn)題了。
以上腳本的簡(jiǎn)單說(shuō)明:用charindex函數(shù)替換like,避免拼接sql語(yǔ)句;使用case when 語(yǔ)句,當(dāng)傳遞的參數(shù)值為空字符串時(shí)讓條件始終為真,即等于忽略該條件,不為空串時(shí)按參數(shù)值模糊查詢。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。