偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

SQL Server解惑——查詢條件IN中能否使用變量

運維 數(shù)據(jù)庫運維
在SQL Server的查詢條件中,能否在IN里面使用變量呢?如果可以的話,有沒有需要注意的地方或一些限制呢?

本文轉載自微信公眾號「DBA閑思雜想錄」,作者瀟湘隱者 。轉載本文請聯(lián)系DBA閑思雜想錄公眾號。   

在SQL Server的查詢條件中,能否在IN里面使用變量呢?如果可以的話,有沒有需要注意的地方或一些限制呢?在回答這個問題前,我們先來看看這個例子:

  1. IF EXISTS (SELECT 1 FROM sys.objects WHERE name='TEST' AND type='U'
  2. BEGIN 
  3.  DROP TABLE TEST; 
  4. END 
  5. GO 
  6. CREATE TABLE TEST ( ID INTNAME VARCHAR(16) ); 
  7. GO 
  8.  
  9. INSERT INTO dbo.TEST 
  10. SELECT 1, 'a'  UNION ALL 
  11. SELECT 2, 'b'  UNION ALL 
  12. SELECT 3, 'c'  UNION ALL 
  13. SELECT 4, 'a,b'UNION ALL 
  14. SELECT 5, '''b'',''c''' UNION ALL 
  15. SELECT 6, '''b'
  16. GO 

如下所示,如果查詢條件里面,變量只有一個值,此時SQL是正常的。

  1. DECLARE @name VARCHAR(16); 
  2. SET @name='a'
  3.  
  4. SELECT * FROM TEST WHERE name IN (@name); 
  5. GO 
  6.  
  7. DECLARE @name VARCHAR(16); 
  8. SET @name='a,b'
  9.  
  10. SELECT * FROM TEST WHERE name IN (@name); 
  11. GO 

如果我們想在查詢條件IN里面輸入多個值呢?假如有這樣的一個需求,一個變量里面包含b和c的值,現(xiàn)在用'b|c’作為條件傳入,對其進行拆分為變量'b'和'c', 想查出name=b 和name=c的記錄,如下截圖所示,SQL其實并沒有按你所“設想/預想”的查出對應記錄,而是將ID=5的記錄查出來了

  1. DECLARE @name1 VARCHAR(16); 
  2. DECLARE @name2 VARCHAR(16); 
  3. SET @name1='b|c'
  4. SET @name2=REPLACE(@name1,'|',''','''
  5. SELECT @name2 
  6.  
  7. SELECT * FROM TEST WHERE name IN (('''' + @name2 + '''')); 

下面這個SQL也是同樣的結果。

  1. DECLARE @name1 VARCHAR(16); 
  2. DECLARE @name2 VARCHAR(16); 
  3. SET @name1='b|c'
  4. SET @name2='''' + REPLACE(@name1,'|',''',''') +'''' 
  5. SELECT @name2 
  6.  
  7. 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解決問題,似乎沒啥好說的,如下例子所示:

  1. DECLARE @sql_cmd NVARCHAR(max); 
  2. DECLARE @name VARCHAR(16); 
  3.  
  4. SET @name='b|c'
  5. SET @sql_cmd='SELECT * FROM TEST WHERE name IN (''' + REPLACE(@name,'|',''',''') +''');' 
  6.  
  7. EXEC sp_executesql @sql_cmd; 

2:使用臨時表或表變量

以這個例子來說,就是將字符串拆分,放入臨時表或表變量,然后關聯(lián)表也好,在IN里面使用子查詢也OK。

3:借助STRING_SPLIT()

  1. DECLARE @name VARCHAR(16); 
  2.  
  3. SET @name='b|c'
  4. SELECT *FROM  test WHERE name IN (SELECT value FROM STRING_SPLIT(@name'|')) 

注意:STRING_SPLIT函數(shù)只有較高版本才支持,SQL Server 2017或SQL Server 2016部分版本支持。

4:借助XML函數(shù)來解決問題

  1. DECLARE @name VARCHAR(16); 
  2. DECLARE @xml_para XML; 
  3.  
  4. SET @name = 'b|c'
  5. SET @xml_para = CAST(( '<A>' + REPLACE(@name'|''</A><A>') + '</A>' ) AS XML); 
  6.  
  7.  
  8. SELECT  * 
  9. FROM    dbo.TEST 
  10. WHERE   NAME IN ( SELECT    A.value('.''varchar(max)'AS [Column
  11.                   FROM      @xml_para.nodes('A'AS FN ( A ) ); 

 

責任編輯:武曉燕 來源: DBA閑思雜想錄
相關推薦

2021-02-03 08:01:35

SQLServerLIKE

2010-11-09 15:18:37

SQL Server多

2011-07-04 14:28:18

SQL Server分區(qū)

2010-10-21 11:10:57

SQL Server查

2010-10-21 10:28:13

SQL Server查

2021-01-07 09:20:08

SQL字符串Server

2010-11-09 13:28:13

SQL SERVER查

2010-07-16 08:50:00

SQL Server表

2010-09-14 16:36:34

SQL SERVER查

2011-08-14 23:26:30

激光打印機常見問題

2010-06-29 17:52:02

SQL Server嵌

2010-09-03 14:56:12

SQLSELECT語句

2010-09-06 17:11:14

SQL函數(shù)

2011-03-29 13:22:07

SQL Server臨時表表變量

2021-12-14 07:05:00

SQL語句數(shù)據(jù)庫

2012-07-11 23:10:49

SQL Server數(shù)據(jù)庫

2010-10-21 10:42:30

SQL Server查

2011-04-15 11:43:24

SQL Server

2011-03-21 10:26:10

SQL Server視圖管理

2010-07-22 16:02:29

點贊
收藏

51CTO技術棧公眾號