如何用T-SQL的STRING_SPLIT提取姓名的名和姓?
T-SQL用STRING_SPLIT提取名和姓的正确方法及问题解析
你遇到的问题原因
- value列未声明报错:STRING_SPLIT是表值函数,必须通过
FROM子句调用才能访问它返回的value列,直接写value相当于引用未定义的变量,自然报错。 - 返回2行NULL:通常是因为待拆分的全名里有多余空格(比如连续空格、首尾空格),STRING_SPLIT默认会把这些空格拆分出空值行,导致结果出现空行和NULL。
- value(1)无效:
ordinal是SQL Server 2022及以后版本才支持的属性,而且它是返回结果的一列,不是数组索引,不能用value(1)这种语法来取值,必须通过筛选ordinal的数值来定位元素。
正确实现方法
情况1:SQL Server 2022及以上版本(支持ordinal参数)
直接启用ordinal属性来定位第一个(名)和最后一个(姓)元素,同时过滤空值避免无效行:
DECLARE @fullName NVARCHAR(100) = '张三 李四'; -- 替换成你的全名变量 DECLARE @firstName NVARCHAR(50), @lastName NVARCHAR(50); -- 提取名(第一个有效元素) SELECT @firstName = value FROM STRING_SPLIT(@fullName, ' ', 1) -- 第三个参数1启用ordinal WHERE ordinal = 1 AND value <> ''; -- 提取姓(最后一个有效元素) SELECT @lastName = value FROM STRING_SPLIT(@fullName, ' ', 1) WHERE ordinal = (SELECT MAX(ordinal) FROM STRING_SPLIT(@fullName, ' ', 1) WHERE value <> ''); SELECT @firstName AS 名, @lastName AS 姓;
情况2:SQL Server 2019及以下版本(无ordinal支持)
用ROW_NUMBER()生成行号来替代ordinal的定位功能,同时过滤空值:
DECLARE @fullName NVARCHAR(100) = '张三 李四'; DECLARE @firstName NVARCHAR(50), @lastName NVARCHAR(50); WITH SplitNames AS ( SELECT value, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn -- 生成行号 FROM STRING_SPLIT(@fullName, ' ') WHERE value <> '' -- 过滤空值行 ) SELECT @firstName = MAX(CASE WHEN rn = 1 THEN value END), @lastName = MAX(CASE WHEN rn = (SELECT MAX(rn) FROM SplitNames) THEN value END) FROM SplitNames; SELECT @firstName AS 名, @lastName AS 姓;
额外注意点
- 如果全名中间可能有多个空格,务必保留
WHERE value <> ''过滤空值,避免错误提取空内容。 - 若全名格式固定为“名 姓”(仅一个分隔空格),可以简化逻辑,但保留空值过滤依然是好习惯,防止异常输入。
内容的提问来源于stack exchange,提问作者user22019322
相关产品推荐
相关产品推荐

