在SQL存储过程的开发过程中,字符串分割与解析是非常常见的需求,比如处理前端传入的逗号分隔的ID列表、解析日志中的多段结构化内容等。不同的场景需要选择不同的实现方式,下文将分别介绍内置函数和自定义函数的使用方法。

使用内置STRING_SPLIT函数实现基础分割
SQL Server 2016及以上版本提供了内置的STRING_SPLIT函数,能够快速将单个分隔符拼接的字符串拆分为多行结果,适合简单的分割场景。
函数基本语法
STRING_SPLIT ( string , separator ),其中string是要分割的原始字符串,separator是分隔符,函数返回一个包含value列的表,每一行对应分割后的一个子字符串。
存储过程中的使用示例
以下示例实现了一个存储过程,接收逗号分隔的用户ID字符串,查询这些用户的基础信息:
-- 创建存储过程
CREATE PROCEDURE GetUserByIds
@IdList NVARCHAR(MAX) -- 接收逗号分隔的ID字符串
AS
BEGIN
SET NOCOUNT ON;
-- 使用STRING_SPLIT分割字符串,关联用户表查询
SELECT u.id, u.user_name, u.age
FROM sys_user u
INNER JOIN STRING_SPLIT(@IdList, ',') s ON u.id = s.value;
END
GO
-- 调用存储过程
EXEC GetUserByIds '1001,1002,1003';
内置函数的局限性
- 仅支持单个字符作为分隔符,无法处理多字符分隔符比如"||"的情况
- 分割结果不保留空值,如果原始字符串中存在连续分隔符,对应的空字符串会被忽略
- 没有返回子字符串在原字符串中的位置序号,无法满足需要按顺序处理的场景
自定义函数实现复杂分割解析
当遇到内置函数无法覆盖的复杂场景时,可以创建自定义表值函数来实现更灵活的分割逻辑,支持多字符分隔符、保留空值、返回位置序号等需求。
支持多字符分隔符的自定义函数示例
以下函数支持传入任意长度的分隔符,同时返回子字符串内容和对应的位置序号:
CREATE FUNCTION dbo.SplitStringComplex
(
@InputStr NVARCHAR(MAX), -- 原始字符串
@Separator NVARCHAR(50) -- 分隔符,支持多字符
)
RETURNS @Result TABLE
(
Seq INT, -- 子字符串位置序号,从1开始
SplitValue NVARCHAR(MAX) -- 分割后的子字符串
)
AS
BEGIN
DECLARE @StartIndex INT = 1;
DECLARE @SeparatorIndex INT;
DECLARE @Seq INT = 1;
DECLARE @SeparatorLen INT = LEN(@Separator);
-- 循环查找分隔符位置
WHILE 1 = 1
BEGIN
-- 查找下一个分隔符的位置
SET @SeparatorIndex = CHARINDEX(@Separator, @InputStr, @StartIndex);
IF @SeparatorIndex = 0
BEGIN
-- 没有更多分隔符,插入最后一段内容
INSERT INTO @Result VALUES (@Seq, SUBSTRING(@InputStr, @StartIndex, LEN(@InputStr) - @StartIndex + 1));
BREAK;
END
ELSE
BEGIN
-- 插入当前分隔符前的内容
INSERT INTO @Result VALUES (@Seq, SUBSTRING(@InputStr, @StartIndex, @SeparatorIndex - @StartIndex));
-- 更新起始位置到分隔符之后
SET @StartIndex = @SeparatorIndex + @SeparatorLen;
SET @Seq = @Seq + 1;
END
END
RETURN;
END
GO
自定义函数在存储过程中的使用
以下存储过程使用上述自定义函数处理以"||"分隔的字符串,同时解析对应的描述信息:
CREATE PROCEDURE ParseMultiFieldString
@DataStr NVARCHAR(MAX), -- 数据字符串,格式为 值1||值2||值3
@DescStr NVARCHAR(MAX) -- 描述字符串,格式为 描述1||描述2||描述3
AS
BEGIN
SET NOCOUNT ON;
-- 分别分割两个字符串,通过序号关联
SELECT d.Seq, d.SplitValue AS DataItem, c.SplitValue AS DescItem
FROM dbo.SplitStringComplex(@DataStr, '||') d
INNER JOIN dbo.SplitStringComplex(@DescStr, '||') c ON d.Seq = c.Seq;
END
GO
-- 调用存储过程
EXEC ParseMultiFieldString 'A||B||C', '描述A||描述B||描述C';
两种方式的适用场景总结
| 实现方式 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| STRING_SPLIT内置函数 | 简单单字符分隔、不需要空值、不需要位置序号的场景 | 性能高,无需额外创建函数,语法简单 | 功能有限,不支持复杂分隔规则 |
| 自定义分割函数 | 多字符分隔、需要保留空值、需要位置序号、复杂解析逻辑的场景 | 灵活度高,可定制逻辑满足各类需求 | 需要提前创建函数,复杂逻辑下性能略低于内置函数 |
在实际开发中,建议先判断场景复杂度,优先使用内置函数提升性能,当内置函数无法满足需求时再选择自定义函数实现,同时可以根据业务需求对自定义函数做进一步优化,比如添加空值过滤参数、支持正则匹配分隔等。
SQL存储过程STRING_SPLIT字符串分割自定义函数修改时间:2026-07-11 13:03:36