成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

本文轉載自微信公眾號「DBA閑思雜想錄」,作者瀟湘隱者 。轉載本文請聯系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的值,現在用'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 ); 

為什么出現了這樣的結果呢?查了大量的官方文檔,沒有看到關于這個問題的介紹和解釋。如果一定要解釋上面現象的情況的話,那么是因為SELECT * FROM TEST WHERE name IN (@name2 ); 其實轉化為了SELECT * FROM TEST WHERE name =@name2; 也就是說,上面SQL并不會按你所“設想”的邏輯運算。而是做了一個轉換,為什么說是這樣的一個轉換呢?當然這也是一個猜想,上面構造的例子也是為了側面驗證這個猜想,另外,上面兩個SQL實際執行計劃的參數列表(Parameter List)也側面印證了這個猜想(如下截圖所示)。如果執行計劃解析成我們想要的結果,那么Parameter List應該是'b' 和‘c'

解決方案:

1:使用動態SQL

使用動態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:使用臨時表或表變量

以這個例子來說,就是將字符串拆分,放入臨時表或表變量,然后關聯表也好,在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函數只有較高版本才支持,SQL Server 2017或SQL Server 2016部分版本支持。

4:借助XML函數來解決問題

  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分區

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查

2010-06-29 17:52:02

SQL Server嵌

2011-08-14 23:26:30

激光打印機常見問題

2010-09-03 14:56:12

SQLSELECT語句

2011-03-29 13:22:07

SQL Server臨時表表變量

2010-09-06 17:11:14

SQL函數

2021-12-14 07:05:00

SQL語句數據庫

2012-07-11 23:10:49

SQL Server數據庫

2010-07-22 16:02:29

2010-09-28 14:59:29

sql查詢

2010-10-21 10:42:30

SQL Server查

2011-04-15 11:43:24

SQL Server
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本三级电影免费观看 | 欧美日高清 | 欧美成人一区二区三区 | 久久国产精品一区 | 久久成人精品视频 | 国产精品久久久久久久久久免费看 | 久久精品亚洲一区二区三区浴池 | 男人天堂网址 | 91久久久精品国产一区二区蜜臀 | 成人性生交大片免费看中文带字幕 | 盗摄精品av一区二区三区 | 91亚洲免费 | 午夜看片网站 | 国产精品一区二区三区四区五区 | 中文精品视频 | 成人在线免费看 | 国产成人啪免费观看软件 | 国产婷婷色综合av蜜臀av | 嫩草影院黄 | 色婷婷婷婷色 | 欧美亚洲视频在线观看 | 国产精品国产三级国产aⅴ中文 | 欧美日韩国产一区二区 | 欧美日韩高清在线观看 | 国产一区二区三区在线视频 | 超碰在线97国产 | 观看av| 成人a视频片观看免费 | 羞羞色视频 | 超碰成人免费观看 | 国产精品人人做人人爽 | 亚洲精品乱码久久久久久按摩观 | 91久久精品一区二区二区 | 国产精品无码久久久久 | 亚洲一区久久 | 国产乱码精品1区2区3区 | 中文字幕一区二区在线观看 | 日韩精品久久 | 亚洲成人日韩 | 夜夜爽99久久国产综合精品女不卡 | 99久久久99久久国产片鸭王 |