SQL Server查詢條件IN中能否使用變量的示例詳解
在SQL Server的查詢條件中,能否在IN里面使用變量呢? 如果可以的話,有沒有需要注意的地方或一些限制呢?在回答這個問題前,我們先來看看這個例子:
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
如下所示,如果查詢條件里面,變量只有一個值,此時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
如果我們想在查詢條件IN里面輸入多個值呢?假如有這樣的一個需求,一個變量里面包含b和c的值,現(xiàn)在用'b|c'作為條件傳入,對其進行拆分為變量'b'和'c', 想查出name=b 和name=c的記錄,如下截圖所示,SQL其實并沒有按你所“設想/預想”的查出對應記錄,而是將ID=5的記錄查出來了
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 + ''''));
下面這個SQL也是同樣的結果。
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)了這樣的結果呢? 查了大量的官方文檔,沒有看到關于這個問題的介紹和解釋。如果一定要解釋上面現(xiàn)象的情況的話,那么是因為SELECT * FROM TEST WHERE name IN (@name2 ); 其實轉化為了SELECT * FROM TEST WHERE name =@name2; 也就是說,上面SQL并不會按你所“設想”的邏輯運算。而是做了一個轉換,為什么說是這樣的一個轉換呢? 當然這也是一個猜想,上面構造的例子也是為了側面驗證這個猜想,另外,上面兩個SQL實際執(zhí)行計劃的參數(shù)列表(Parameter List)也側面印證了這個猜想。如果執(zhí)行計劃解析成我們想要的結果,那么Parameter List應該是'b' 和‘c'
解決方案:
1:使用動態(tài)SQL
使用動態(tài)SQL解決問題,似乎沒啥好說的,如下例子所示:
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:使用臨時表或表變量
以這個例子來說,就是將字符串拆分,放入臨時表或表變量,然后關聯(lián)表也好,在IN里面使用子查詢也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ù)來解決問題
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 ) );
到此這篇關于SQL Server查詢條件IN中能否使用變量的文章就介紹到這了,更多相關sqlserver條件查詢in內容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持本站!
版權聲明:本站文章來源標注為YINGSOO的內容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。