如何在SQL函数fnBuildABC中按斜杠拆分Location字段获取指定分段
实现fnBuildABC函数的几种思路(无需逐字符检查)
针对你的需求,以下是几种SQL Server中无需逐字符检查即可实现字符串按斜杠拆分并返回指定段的方案,适配不同版本的SQL Server:
方案1:利用PARSENAME函数(简洁但有长度限制)
PARSENAME原本用于解析SQL对象名(按点拆分),可以通过替换斜杠为点来复用该函数。优点是代码极简,但仅支持长度不超过128字符的字符串(因为PARSENAME参数为sysname类型,即NVARCHAR(128))。
CREATE FUNCTION dbo.fnBuildABC ( @Location NVARCHAR(128), @Segment INT ) RETURNS NVARCHAR(128) AS BEGIN -- 将斜杠替换为点,适配PARSENAME的拆分规则 SET @Location = REPLACE(@Location, '/', '.'); -- PARSENAME从右往左计数,因此段号与参数做反向映射 RETURN CASE @Segment WHEN 1 THEN PARSENAME(@Location, 3) WHEN 2 THEN PARSENAME(@Location, 2) WHEN 3 THEN PARSENAME(@Location, 1) ELSE NULL -- 处理无效段号 END; END;
方案2:使用STRING_SPLIT(SQL Server 2022+ 推荐)
SQL Server 2022及以上版本的STRING_SPLIT支持enable_ordinal参数,可直接返回拆分后的序号,无需额外处理顺序,高效且支持长字符串。
CREATE FUNCTION dbo.fnBuildABC ( @Location NVARCHAR(MAX), @Segment INT ) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @Result NVARCHAR(MAX); SELECT @Result = value FROM STRING_SPLIT(@Location, '/', 1) -- 启用序号返回 WHERE ordinal = @Segment; RETURN @Result; END;
方案3:OPENJSON兼容方案(SQL Server 2016-2019)
若使用2016-2019版本(无enable_ordinal参数),可通过OPENJSON将字符串转为JSON数组,利用数组下标确定段位置:
CREATE FUNCTION dbo.fnBuildABC ( @Location NVARCHAR(MAX), @Segment INT ) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @Result NVARCHAR(MAX); -- 将字符串转为JSON数组,拆分斜杠分隔的内容 SELECT @Result = value FROM OPENJSON('["' + REPLACE(STRING_ESCAPE(@Location, 'json'), '/', '","') + '"]') WHERE [key] + 1 = @Segment; -- JSON下标从0开始,加1匹配段号 RETURN @Result; END;
方案4:XML解析方案(兼容SQL Server 2008+)
对于更早版本的SQL Server,可通过XML解析实现拆分,兼容性最强:
CREATE FUNCTION dbo.fnBuildABC ( @Location NVARCHAR(MAX), @Segment INT ) RETURNS NVARCHAR(MAX) AS BEGIN IF @Location IS NULL OR @Location = '' RETURN NULL; -- 将字符串包装为XML节点,用斜杠拆分 DECLARE @Xml XML = '<root><item>' + REPLACE(@Location, '/', '</item><item>') + '</item></root>'; -- 根据段号提取对应节点的值 RETURN @Xml.value('(/root/item[position()=sql:variable("@Segment")]/text())[1]', 'NVARCHAR(MAX)'); END;
测试验证
针对你的测试数据:
- 输入
'1/21/s15'和段号1,返回'1';段号2返回'21';段号3返回's15' - 输入
'1//'和段号2,返回空字符串 - 输入
'9//72'和段号3,返回'72'
所有方案均能满足需求,可根据你的SQL Server版本和字符串长度需求选择合适的实现。
内容的提问来源于stack exchange,提问作者Jonathan Small
相关产品推荐
相关产品推荐

