首页 > 数据库 >T-SQL——将字符串转为单列

T-SQL——将字符串转为单列

时间:2023-02-25 08:11:12浏览次数:70  
标签:dbo -- 单列 Ids Str SQL 字符串 SELECT

目录

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'; 

标签:dbo,--,单列,Ids,Str,SQL,字符串,SELECT
From: https://www.cnblogs.com/shanzhiming/p/17143951.html

相关文章

  • 求字符串中最长长度的字串
    题目给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。今天做题时间有点晚,之前学习算法与数据结构,解决方法好像是用kmp算法来着,今天想发一......
  • Mysql
    底层架构   存储引擎1、InnoDB存储引擎InnoDB是MySQL的默认事务型引擎,它被设计用来处理大量的短期(short-lived)事务。除非有非常特别的原因需要使用其他的存储引......
  • 【LeeCode】1208. 尽可能使字符串相等
    【题目描述】给你两个长度相同的字符串,​​s​​​ 和 ​​t​​。将 ​​s​​ 中的第 ​​i​​ 个字符变到 ​​t​​ 中的第 ​​i​​ 个字符需要 ​​|s[i......
  • 关于SQLsever2012报错的一些经验总结
    问题描述:数据库连接实例时出现报错情况;问题截图:  故障软件:SQLsever2012操作系统:windowssever2022R2数据中心期望结果:可以打开之前的实例 总结经验: 上面这......
  • Mysql数据库的表结构
    【INFORMATION_SCHEMA数据库】 是MySQL自带的,它提供了访问数据库 元数据 的方式,元数据:数据库名或表名,列的数据类型,或访问权限等。在MySQL中,把【INFORMATION_SCHEMA】......
  • docker部署mysql
    搜索mysql镜像dockersearchmysql拉取mysql镜像dockerpullmysql:5.7创建容器,设置端口映射、目录映射mkdir~/mysqlcd~/mysqldockerrun-id\-p330......
  • MYSQL的存储引擎以及系统数据库
    今天分享的是mysql的存储引擎,以及mysql数据库中相关配置状态和相关的变量存储引擎MyISAM存储引擎MyISAM引擎特点不支持事务表级锁定读写相互阻塞,写入不能读,读时不能写只缓......
  • Redis设计与实现—简单动态字符串、链表、字典
    前言《Redis设计与实现》数据结构部分有关字符串类型介绍。@目录前言一、数据结构——简单动态字符串1.1SDS定义1.2SDS与C字符串的区别1.2.1常数复杂度获取字符串长度......
  • Mysql、(一)Linux下Mysql 基础操作
    @目录一、Linux下安装Mysql二、启动Mysql服务三、登录Mysql四、用户权限五、Mysql的配置文件一、Linux下安装Mysql百度二、启动Mysql服务servicemysqlstartservic......
  • Mysql、(八) 主从复制
    @目录一、MySQL主从复制步骤二、主从复制的配置主机的配置从机的配置其它操作一、MySQL主从复制步骤Master将改变记录到二进制日志(binarylog)。这些记录过程叫做二......