shanzm-2023年2月22日

0. 背景

代码中执行存储过程,参数是多个且不确定数量,期望SQL查询时使用该参数作为IN的筛选条件

比如说,具体参数@Ids="1,2,3,4",

期望在存储过程中,实现 select * from Table where id In @Ids

直接这样写会报错

(当然可以使用动态sql 进行拼接,但不需要这么做),而是将传递的参数分裂为单列的行记录!


1. 使用STRING_SPLIT函数

  • Sql Server在2016版本中支持使用STRING_SPLIT函数

    • 可以将字符串按照分隔符,切割成一个数据表
  • 若是低版本数据使用提示对象名 'STRING_SPLIT' 无效。

SELECT * FROM STRING_SPLIT('1,2,3,4,5', ',');

--结果:
value
-------------
1
2
3
4
5

2. 自定义分裂函数

  • 实现方式1:基于字符串操作

    • 将目标字符串末尾拼接上一个分隔符
    • 从字符串第一个位置开始查询分隔符在字符串中第一次出现的位置索引
    • 从左截取(第一个分隔符索引-1)长度的字符串,此外分裂出的第一个结果
    • 将目标字符串从第一个分隔符之前的替换为空
    • 循环上述2~4步骤
-- ======================================================
-- Author: shanzm
-- Create date: 2021年6月30日 15:52:02
-- Description: 将指定字符串按照指定的分裂符分裂为单列表
-- ======================================================
ALTER FUNCTION [dbo].[funGetSplitStr]
(
@Str VARCHAR(8000), --目标字符串,形如"a,b,c"
@StrSeprate VARCHAR(1) --分隔符,形如","
)
RETURNS @temp TABLE --返回表值变量,只有一列F1
(
F1 VARCHAR(100)
)
AS
BEGIN
DECLARE @ch AS VARCHAR(100);
SET @Str = @Str + @StrSeprate;
WHILE (@Str <> '')
BEGIN
SET @ch = LEFT(@Str, CHARINDEX(@StrSeprate, @Str, 1) - 1);
INSERT @temp
VALUES
(@ch);
SET @Str = STUFF(@Str, 1, CHARINDEX(@StrSeprate, @Str, 1), '');
END;
RETURN;
END;
  • 实现方式2:基于XML
-- ======================================================
-- Author: shanzm
-- Create date: 2021年6月30日 15:52:02
-- Description: 将指定字符串按照指定的分裂符分裂为单列表
-- ======================================================
CREATE FUNCTION dbo.funGetSplitStr2
(
@str varchar(1000),
@strSperate varchar(10)
)
RETURNS @tableVar TABLE
(
F1 VARCHAR(100)
)
AS
BEGIN
DECLARE @xmlstr XML;
--SET ARITHABORT ON;
SET @xmlstr = CONVERT(XML, '<root><v>' + REPLACE(@str, @strSperate, '</v><v>') + '</v></root>');
--SELECT @xmlstr; INSERT INTO @tableVar
SELECT F1 = N.v.value('.', 'varchar(100)') FROM @xmlstr.nodes('/root/v') N(v);
RETURN;
END;
GO --测试
SELECT * FROM funGetSpliterStr2('1.2.3','.') --结果 F1
---------
1
2
3 (3 行受影响)

3. 使用示例

代码中传递的参数@Ids="1,2,3,4",执行存储过程作为筛选条件

这里任意使用一个测试表Company,该表有一个Id字段,存储过程简单的演示了Ids字符串进行查询

  • 创建测试存储过程
CREATE PROCEDURE [dbo].[proTest]
@Ids VARCHAR(500)
AS
BEGIN
SELECT *
FROM dbo.Company
WHERE Id IN
(
SELECT F1 FROM dbo.funGetSplitStr(@Ids, ',')
);
END; EXEC dbo.proTest @Ids = '1,3';

T-SQL——将字符串转为单列的更多相关文章

  1. 【SQL】sql版Split函数。用于拆分字符串为单列表格

    功能与.net版string.Split函数类似,只不过.net返回的是数组,这个返回的是一个单列表格,每个拆分出来的子串占一行.可选是否移除空格子串和重复项.市面上类似的函数不算少,但大多都是在循环 ...

  2. 日期字符串转为java.sql.Date

    日期字符串转为java.sql.Date类型 问题引出:在将一个日期字符串通过sql语句,插入到数据表的日期字段(字段类型是DATE),时遇到一个问题,如何将一个日期字符串转成java.sql.Dat ...

  3. SQL SERVER 字符串函数 STRING_SPLIT()

    定义: STRING_SPLIT()函数根据指定的分隔符将字符串拆分为子字符串行. ※STRING_SPLIT 要求兼容性级别至少为 130. (即SSMS 2016及以上版本) ※级别低于 130 ...

  4. [LeetCode] String to Integer (atoi) 字符串转为整数

    Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. ...

  5. MSSQL Server数据库的四种连接方法和sql连接字符串

    MSSQL Server数据库的四种连接方法和sql连接字符串 分类: [ 03 ] C#(131) [ 07 ] SQL Server(68) [ 01 ] .NET(189) 今天用SQL Ser ...

  6. [C++] zlatlcv: ATL字符串转换辅助库。能很方便的将UTF-8字符串转为TCHAR等字符串

    作者:zyl910 如今,UTF-8字符串的使用频率越来越多了.但是在VC中,不能直接处理UTF-8字符串,得专门去写UTF-8与窄字符串.宽字符串.TCHAR字符串相互转换的代码.不仅费时费力,而且 ...

  7. sql 解析字符串添加到临时表中 sql存储过程in 参数输入

    sql 解析字符串添加到临时表中  sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表   FROM dbo.Func_SplitOneCol ...

  8. sql2008 将行转为字符串, 将字符串转为行 互转

    --将行转为字符串 select stuff((select top 20 ','+ QQ from dl_QQ where uiid=1 order by tim desc for xml path ...

  9. json格式的字符串转为json对象遇到特殊字符问题解决

    中午做后台发过来的json的时候转为对象,可是有几条数据一直出不来,检查发现json里包含了换行符,造成这种情况的原因可能是编辑部门在编辑的时候打的回车造成的 假设有这样一段json格式的字符串 va ...

  10. DataTable转json字符串,jQuery.parseJSON()把json字符串转为标准的json对象格式

    1.string res = DataTableToJson.DataTable2Json(dt);讲DataTable转换为json字符串 http://www.365mini.com/page/j ...

随机推荐

  1. sql注入的一丢丢

  2. <一>智能指针基础

    代码1 int main(){ //裸指针,手动开辟,需要自己释放,如果忘记了或者因为 //程序逻辑导致p没有释放,那么就会导致内存泄漏 int *p=new int(10); if(***){ re ...

  3. 【数据库】Postgresql、PG的分区操作:创建、删除指定分区,非分区表转分区表

    〇.参考链接 一.为表创建指定分区 -- 表创建分区 参数 表名 分区序列 例如: ltc_customer , 20220915 则创建 ltc_customer_20220915 分区表 CREA ...

  4. (java 实现开箱即用基于 redis 的分布式锁

    项目简介 lock 为 java 设计的分布式锁,开箱即用,纵享丝滑. 开源地址:https://github.com/houbb/lock 目的 开箱即用,支持注解式和过程式调用 基于 redis ...

  5. 02- 快速入门MybatisPlus

    创建表 现有一张 User 表,其表结构如下: id name age email 1 Jone 18 test1@baomidou.com 2 Jack 20 test2@baomidou.com ...

  6. [python]《Python编程快速上手:让繁琐工作自动化》学习笔记5

    1. 处理CSV文件笔记(第14章) (代码下载) 本文主要在python下介绍CSV文件,CSV 表示"Comma-Separated Values(逗号分隔的值)",CSV文件 ...

  7. C#开发的插件程序 - 开源研究系列文章

    上次编写了一个家庭小助手的小工具软件,也对其中的线程池及管理器进行了介绍(见博文:C#开发的线程池和管理器 - 开源研究系列文章),这次把里面的插件部分的功能单独放出来进行介绍,让更多的朋友能够进行学 ...

  8. Git操作不规范,战友提刀来相见!

    年终奖都没了,还要扣我绩效,门都没有,哈哈. 这波骚Git操作我也是第一次用,担心闪了腰,所以不仅做了备份,也做了笔记,分享给大家. 文末留言,聊聊你的年终奖. 问题描述 小A和我在同时开发一个功能模 ...

  9. CVE-2022-32532 Apache Shiro 身份认证绕过

    漏洞名称 CVE-2022-32532 Apache Shiro 身份认证绕过 利用条件 Apache Shiro < 1.9.1 漏洞原理 使用RegexRequestMatcher进行权限配 ...

  10. (15)go-micro微服务main.go开发

    目录 一 导包 二 配置中心 三 注册中心 四 zap日志初始化 五 初始化Mysql数据库 六 初始化Redis连接 七 注册服务 八 初始化服务 九 注册 handle 十 启动服务 十一 mai ...