stuff是sql server中「删除一段+插入一段」的原子操作函数,语法为stuff(string, start, length, replacement),其中start从1开始,length为0时不删只插,start超长返回原串,负值报错。

STUFF函数的基本用法和参数含义
STUFF 不是“删除并替换指定位置的字符”的通用工具,而是 SQL Server 特有的字符串拼接/截断函数,它本质是「删除一段 + 插入一段」的原子操作。它的签名是:STUFF(string, start, length, replacement),其中:
-
string是原始字符串(varchar/nvarchar) -
start是起始位置(从 1 开始计数,不是 0) -
length是要删除的字符个数;若为 0,则不删只插 -
replacement是插入的新字符串(可为空字符串'')
注意:start 超出字符串长度时返回原串;start 为负数或 length 为负会报错 Argument data type varchar is invalid for argument 3 of stuff function。
想“删除指定位置字符”?别直接填 length=1 就完事
常见误解:以为删第 5 个字符就写 STUFF(col, 5, 1, '') —— 这确实能删,但必须确认 col 长度 ≥5。否则结果不可控(比如空值或截断失败)。更稳妥的做法是加长度判断:
SELECT
CASE
WHEN LEN(col) >= 5 THEN STUFF(col, 5, 1, '')
ELSE col
END AS result
FROM your_table;
另外,如果目标是“删掉某位置之后的所有字符”,length 可设为一个足够大的数(如 LEN(col)),但更推荐用 LEFT(col, 4),语义更清晰、性能略优。
用STUFF做字符串拼接?小心空值陷阱
很多人用 STUFF 配合 FOR XML 或 STRING_AGG(SQL Server 2017+)做去重拼接,典型模式是:
STUFF((
SELECT ',' + name
FROM users u2
WHERE u2.group_id = u1.group_id
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
这里容易踩的坑:
- 子查询里
name为NULL会导致整个拼接结果变NULL(',' + NULL → NULL),需显式过滤或用ISNULL(name, '') -
FOR XML PATH('')在含特殊字符(如&、)时会自动转义,得用 <code>.value('.', 'NVARCHAR(MAX)')解码 - SQL Server 2017+ 优先用
STRING_AGG(name, ','),更简洁且原生支持ORDER BY和NULL处理
跨数据库兼容性问题:STUFF不是标准SQL
STUFF 是 SQL Server 独有函数,PostgreSQL、MySQL、Oracle 都不支持。迁移或写通用脚本时务必注意:
- PostgreSQL:用
overlay(str placing newstr from start for len)模拟,但len为 0 时不等价 - MySQL:没有直接对应函数,得组合
CONCAT(LEFT(), RIGHT())或自定义函数 - 如果只是想删固定位置字符,各库都有
SUBSTRING/SUBSTR,组合使用更可移植
真正需要 STUFF 的场景其实很窄:仅限 SQL Server 下做“删+插”一步到位,且插入内容动态、删除长度不确定——这种时候才值得用它,而不是把它当成万能字符串编辑器。











