SQL Server查询条件IN中能否使用变量的示例详解

作者:潇湘隐者 时间:2024-01-15 17:55:55 

在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 Server查询条件IN中能否使用变量的示例详解

如下所示,如果查询条件里面,变量只有一个值,此时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的值,现在用'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 Server查询条件IN中能否使用变量的示例详解

下面这个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 );

为什么出现了这样的结果呢? 查了大量的官方文档,没有看到关于这个问题的介绍和解释。如果一定要解释上面现象的情况的话,那么是因为SELECT * FROM TEST WHERE name IN (@name2 ); 其实转化为了SELECT * FROM TEST WHERE name =@name2; 也就是说,上面SQL并不会按你所“设想”的逻辑运算。而是做了一个转换,为什么说是这样的一个转换呢? 当然这也是一个猜想,上面构造的例子也是为了侧面验证这个猜想,另外,上面两个SQL实际执行计划的参数列表(Parameter List)也侧面印证了这个猜想。如果执行计划解析成我们想要的结果,那么Parameter List应该是'b' 和‘c'

SQL Server查询条件IN中能否使用变量的示例详解

SQL Server查询条件IN中能否使用变量的示例详解

解决方案:

1:使用动态SQL

使用动态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;

SQL Server查询条件IN中能否使用变量的示例详解

2:使用临时表或表变量

以这个例子来说,就是将字符串拆分,放入临时表或表变量,然后关联表也好,在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, '|'))

SQL Server查询条件IN中能否使用变量的示例详解

注意:STRING_SPLIT函数只有较高版本才支持,SQL Server 2017或SQL Server 2016部分版本支持。

4:借助XML函数来解决问题


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中能否使用变量的示例详解

来源:https://www.cnblogs.com/kerrycode/p/14291064.html

标签:sqlserver,条件查询,in
0
投稿

猜你喜欢

  • JS模拟简易滚动条效果代码(附demo源码)

    2024-04-23 09:22:45
  • 在ASP.NET 2.0中操作数据之十:使用 GridView和DetailView实现的主/从报表

    2023-07-02 20:22:40
  • TensorFlow人工智能学习按索引取数据及维度变换详解

    2024-01-04 13:18:55
  • YOLOv5部署到web端详细过程(flask+js简单易懂)

    2023-03-28 07:00:17
  • 使用Python爬虫库requests发送请求、传递URL参数、定制headers

    2023-08-29 09:47:47
  • Python中移除List重复项的五种方法

    2021-12-11 20:15:38
  • Python列表推导式,元组推导式,字典推导式,集合推导式

    2022-08-01 23:26:36
  • jQuery.animate简单分析

    2010-06-26 12:45:00
  • 本地存储localStorage用法详解

    2024-04-30 10:09:11
  • QT连接Oracle数据库并实现登录验证的操作步骤

    2024-01-27 13:06:44
  • 内容呈现的减法

    2007-11-16 16:22:00
  • php中strtotime函数性能分析

    2023-11-22 13:21:05
  • 在IPython中执行Python程序文件的示例

    2023-02-20 09:06:14
  • 详解python3 GUI刷屏器(附源码)

    2022-02-02 12:34:15
  • 准备SQL Server 2008透明数据加密

    2009-01-22 14:18:00
  • Scrapy模拟登录赶集网的实现代码

    2023-02-22 20:33:47
  • MySQL数据库在Linux下二进制日志恢复方法

    2009-07-30 08:55:00
  • python 实现批量替换文本中的某部分内容

    2021-05-19 18:06:42
  • python cv2截取不规则区域图片实例

    2022-08-31 18:58:42
  • aspJpeg图片水印有杂点的完美解决方法

    2011-02-05 10:55:00
  • asp之家 网络编程 m.aspxhome.com