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. NOIP 口胡

    因为没准备啥东西 这两天口胡一下近年 NOIP 的题 大概会一道不落?没什么很寄的考点主要是 2021 T1 报数 打一个 \(O(\log n)\) 查询 \(n\) 中是否有 \(7\),打一个类 ...

  2. CLion和动态链接库

    目录 生成链接库 链接库的使用 生成链接库 创建一个library项目 在项目中写好自己的代码 cmakelist cmake_minimum_required(VERSION 3.21) proje ...

  3. 【day01】redis

    〇.思维导图 1.解决缓存数据库双写不一致 延迟双删(中间sleep一段时间)--写性能下降 内存队列:同一个key(线程)的所有操作丢到队列,串行化执行--实现麻烦&大量内存队列,队列宕机 ...

  4. Navicat破解教程

    一.注意: 软件适用于WIN7/8/10/11: 安装全程断网: 下载.解压和安装都应该在英文路径下进行: 解压安装前关闭所有杀毒软件,WIN10/11系统需关闭Windows Defender的实时 ...

  5. MySQL中这14个牛逼的功能,惊艳到我了!!!

    前言 我最近几年用MYSQL数据库挺多的,发现了一些非常有用的小玩意,今天拿出来分享到大家,希望对你会有所帮助. 1.group_concat 在我们平常的工作中,使用group by进行分组的场景, ...

  6. 2022年7月14日,第四组 周鹏,认识JAVA的第二天(;´д`)ゞ(;д;)

    那天,我遇到了JAVA 然后,我失去了头发 无论我用了多少办法 还是放不下那个它 我哭的像个傻瓜 但也没能留住它 如果再有一次从来 我愿为它披上薄纱 愿它安稳有个家 可我终究还是失去了它 失去了原本为 ...

  7. [编程基础] C++多线程入门10-packaged_task示例

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 10 pa ...

  8. mysql 1366 - Incorrect string value

    mysql 插入中文时报错  mysql 1366 - Incorrect string value... 这是由于 数据库 / 表 / 表字段 编码格式未设置好造成的 解决办法: 1.查看编码是否符 ...

  9. [LeetCode]至少是其他数字两倍的最大数

    题目 代码 class Solution { public: int dominantIndex(vector<int>& nums) { vector<int> so ...

  10. Java连接Zookeeper以及书写简单增删改查的方法

    Java连接Zookeeper以及书写简单增删改查的方法   摘要:本笔记主要记录了使用IDEA创建一个Maven项目并使用Maven配置文件下载Zookeeper连接驱动,连接云服务器的Zookee ...