SQL Server查詢(xún)條件IN中能否使用變量的示例詳解
在SQL Server的查詢(xún)條件中,能否在IN里面使用變量呢? 如果可以的話,有沒(méi)有需要注意的地方或一些限制呢?在回答這個(gè)問(wèn)題前,我們先來(lái)看看這個(gè)例子:
IF EXISTS (SELECT 1 FROM sys.objects WHERE name='TEST' AND type='U') BEGIN DROP TABLE TEST; END GO CREATE TABLE TEST ( ID INT, NAME VARCHAR(16) ); GO INSERT INTO dbo.TEST SELECT 1, 'a' UNION ALL SELECT 2, 'b' UNION ALL SELECT 3, 'c' UNION ALL SELECT 4, 'a,b'UNION ALL SELECT 5, '''b'',''c''' UNION ALL SELECT 6, '''b'; GO
如下所示,如果查詢(xún)條件里面,變量只有一個(gè)值,此時(shí)SQL是正常的。
DECLARE @name VARCHAR(16); SET @name='a'; SELECT * FROM TEST WHERE name IN (@name); GO DECLARE @name VARCHAR(16); SET @name='a,b'; SELECT * FROM TEST WHERE name IN (@name); GO
如果我們想在查詢(xún)條件IN里面輸入多個(gè)值呢?假如有這樣的一個(gè)需求,一個(gè)變量里面包含b和c的值,現(xiàn)在用'b|c'作為條件傳入,對(duì)其進(jìn)行拆分為變量'b'和'c', 想查出name=b 和name=c的記錄,如下截圖所示,SQL其實(shí)并沒(méi)有按你所“設(shè)想/預(yù)想”的查出對(duì)應(yīng)記錄,而是將ID=5的記錄查出來(lái)了
DECLARE @name1 VARCHAR(16); DECLARE @name2 VARCHAR(16); SET @name1='b|c'; SET @name2=REPLACE(@name1,'|',''',''') SELECT @name2 SELECT * FROM TEST WHERE name IN (('''' + @name2 + ''''));
下面這個(gè)SQL也是同樣的結(jié)果。
DECLARE @name1 VARCHAR(16); DECLARE @name2 VARCHAR(16); SET @name1='b|c'; SET @name2='''' + REPLACE(@name1,'|',''',''') +'''' SELECT @name2 SELECT * FROM TEST WHERE name IN (@name2 );
為什么出現(xiàn)了這樣的結(jié)果呢? 查了大量的官方文檔,沒(méi)有看到關(guān)于這個(gè)問(wèn)題的介紹和解釋。如果一定要解釋上面現(xiàn)象的情況的話,那么是因?yàn)镾ELECT * FROM TEST WHERE name IN (@name2 ); 其實(shí)轉(zhuǎn)化為了SELECT * FROM TEST WHERE name =@name2; 也就是說(shuō),上面SQL并不會(huì)按你所“設(shè)想”的邏輯運(yùn)算。而是做了一個(gè)轉(zhuǎn)換,為什么說(shuō)是這樣的一個(gè)轉(zhuǎn)換呢? 當(dāng)然這也是一個(gè)猜想,上面構(gòu)造的例子也是為了側(cè)面驗(yàn)證這個(gè)猜想,另外,上面兩個(gè)SQL實(shí)際執(zhí)行計(jì)劃的參數(shù)列表(Parameter List)也側(cè)面印證了這個(gè)猜想。如果執(zhí)行計(jì)劃解析成我們想要的結(jié)果,那么Parameter List應(yīng)該是'b' 和‘c'
解決方案:
1:使用動(dòng)態(tài)SQL
使用動(dòng)態(tài)SQL解決問(wèn)題,似乎沒(méi)啥好說(shuō)的,如下例子所示:
DECLARE @sql_cmd NVARCHAR(max); DECLARE @name VARCHAR(16); SET @name='b|c'; SET @sql_cmd='SELECT * FROM TEST WHERE name IN (''' + REPLACE(@name,'|',''',''') +''');' EXEC sp_executesql @sql_cmd;
2:使用臨時(shí)表或表變量
以這個(gè)例子來(lái)說(shuō),就是將字符串拆分,放入臨時(shí)表或表變量,然后關(guān)聯(lián)表也好,在IN里面使用子查詢(xún)也OK。
3:借助STRING_SPLIT()
DECLARE @name VARCHAR(16); SET @name='b|c'; SELECT *FROM test WHERE name IN (SELECT value FROM STRING_SPLIT(@name, '|'))
注意:STRING_SPLIT函數(shù)只有較高版本才支持,SQL Server 2017或SQL Server 2016部分版本支持。
4:借助XML函數(shù)來(lái)解決問(wèn)題
DECLARE @name VARCHAR(16); DECLARE @xml_para XML; SET @name = 'b|c'; SET @xml_para = CAST(( '<A>' + REPLACE(@name, '|', '</A><A>') + '</A>' ) AS XML); SELECT * FROM dbo.TEST WHERE NAME IN ( SELECT A.value('.', 'varchar(max)') AS [Column] FROM @xml_para.nodes('A') AS FN ( A ) );
到此這篇關(guān)于SQL Server查詢(xún)條件IN中能否使用變量的文章就介紹到這了,更多相關(guān)sqlserver條件查詢(xún)in內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- sqlserver和oracle中對(duì)datetime進(jìn)行條件查詢(xún)的一點(diǎn)區(qū)別小結(jié)
- MySql帶OR關(guān)鍵字的多條件查詢(xún)語(yǔ)句
- Mysql帶And關(guān)鍵字的多條件查詢(xún)語(yǔ)句
- SQL 多條件查詢(xún)幾種實(shí)現(xiàn)方法詳細(xì)介紹
- linq to sql 中,如何解決多條件查詢(xún)問(wèn)題,答案,用表達(dá)式樹(shù)! (下)
- linq to sql中,如何解決多條件查詢(xún)問(wèn)題,答案,用表達(dá)式樹(shù)!
- MySQL中使用case when 語(yǔ)句實(shí)現(xiàn)多條件查詢(xún)的方法
相關(guān)文章
sqlserver exists,not exists的用法
exists,not exists的使用方法示例,需要的朋友可以參考下。2009-12-12delete誤刪數(shù)據(jù)使用SCN號(hào)恢復(fù)(推薦)
這篇文章主要介紹了使用scn號(hào)恢復(fù)誤刪數(shù)據(jù)問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12SQLServer 數(shù)據(jù)導(dǎo)入導(dǎo)出的幾種方法小結(jié)
在涉及到SQL Server編程或是管理時(shí)一定會(huì)用到數(shù)據(jù)的導(dǎo)入與導(dǎo)出, 導(dǎo)入導(dǎo)出的方法有多種,結(jié)合我在做項(xiàng)目時(shí)的經(jīng)歷做一下匯總2010-06-06SQL點(diǎn)滴24 監(jiān)測(cè)表的變化
在網(wǎng)上看到一篇關(guān)于監(jiān)測(cè)表中的插入,更新,刪除的方法,使用觸發(fā)器實(shí)現(xiàn)的,很有價(jià)值。2011-09-09sql 判斷數(shù)據(jù)庫(kù),表,存儲(chǔ)過(guò)程等是否存在的代碼
sql下用了判斷各種資源是否存在的代碼,很實(shí)用。需要的朋友可以參考下。2009-12-12SQL Server數(shù)據(jù)類(lèi)型轉(zhuǎn)換方法
這篇文章主要為大家詳細(xì)介紹了SQL Server數(shù)據(jù)類(lèi)型轉(zhuǎn)換方法,感興趣的小伙伴們可以參考一下2016-03-03SQL Server 服務(wù)由于登錄失敗而無(wú)法啟動(dòng)
當(dāng)域的密碼被修改過(guò)后,相應(yīng)服務(wù)使用的登陸驗(yàn)證信息不會(huì)自動(dòng)更新需要手動(dòng)來(lái)更新,才能解決此問(wèn)題。如果大家嫌比較麻煩,還是像上面的解決方案那樣直接將登陸身份修改為“本地系統(tǒng)帳戶(hù)”比較簡(jiǎn)單。2010-05-05