stuff是sql server特有函数,语法为stuff(string, start, length, replacement),从第start位(≥1)删length个字符后插入replacement;start超长返回原串,length为0时仅插入,常与isnull或string_agg配合使用。

STUFF函数在SQL Server中怎么用
STUFF不是标准SQL函数,只存在于SQL Server(及Azure SQL),MySQL、PostgreSQL、Oracle都不支持。它本质是「删除+插入」的组合操作,不是纯替换——这点常被误读,导致逻辑出错。
语法是:STUFF(string, start, length, replacement),意思是:从string第start个字符开始,删掉length个字符,再把replacement插进去。
-
start必须 ≥ 1;传0或负数会报错:Argument 2 of the STUFF function cannot be less than 1. -
length可以为0——此时不删任何字符,只做插入(类似字符串前/中拼接) - 如果
start超过原字符串长度,返回replacement本身(不是NULL) - 如果
length超出剩余字符数,就删到末尾,不会报错
想替换第5位开始的3个字符,但原字段可能不足8位怎么办
直接写STUFF(col, 5, 3, 'XYZ')在col长度<5时会返回'XYZ',长度=6时删掉最后2个字符再插——这往往不是你想要的“精准替换”。得加长度判断:
SELECT
CASE
WHEN LEN(col) >= 8 THEN STUFF(col, 5, 3, 'XYZ')
ELSE col -- 或按需补空格、报错、跳过
END AS result
FROM table_name;
注意:LEN()忽略末尾空格,要用DATALENGTH()判字节长(尤其含Unicode时)。
用STUFF拼接多行数据时为什么结果开头多了逗号
这是经典陷阱:有人用STUFF((SELECT ',' + name FROM t FOR XML PATH('')), 1, 1, '')去去重拼接,但若子查询结果为空(没匹配到行),整个SELECT返回NULL,STUFF(NULL, ...)还是NULL——看起来像“没数据”,其实逻辑断了。
- 务必用
ISNULL()兜底:STUFF(ISNULL((SELECT ...), ''), 1, 1, '') - 更安全的做法是加
WHERE过滤空值,或用STRING_AGG(SQL Server 2017+)替代 -
FOR XML PATH('')对特殊字符(如&、)会自动转义,要<code>TYPE.value('.', 'NVARCHAR(MAX)')解码
STUFF和REPLACE函数选哪个
REPLACE是全字符串搜索替换(比如把所有'old'换成'new'),STUFF是位置驱动的“挖洞填坑”。两者不可互换。
- 要改固定位置内容(如身份证第9–10位、订单号前缀)→ 用
STUFF - 要按值替换(如把状态
'P'全改成'Processing')→ 用REPLACE或CASE - 想用
STUFF模拟REPLACE?得先用CHARINDEX找位置,嵌套深、性能差,还处理不了重复匹配
位置敏感的操作,别绕路——STUFF就是干这个的,但得盯紧start和length的边界条件,尤其是空值、截断、Unicode双字节这些地方容易悄无声息出错。










