SQL Server 2017 仅支持 TRIM(' ' FROM col),不支持 TRIM(col)、TRIM(BOTH/LEADING/TRAILING ...);推荐用 LTRIM(RTRIM(col)) 保证兼容性;函数作用于列会导致索引失效;LTRIM/RTRIM 不处理制表符、换行符及全角空格。

SQL Server 2017 支持 TRIM(),但必须写成 TRIM(' ' FROM col),不能省略 ' ' FROM —— 否则直接报错。
TRIM(' ' FROM col) 是唯一合法写法
SQL Server 2017 引入了 TRIM(),但它不接受 MySQL 或 PostgreSQL 那种简写 TRIM(col)。你如果写:
SELECT TRIM(name) FROM users;
会得到错误:Invalid column name 'TRIM'(其实是函数名未识别)。
正确写法只有一种:
-
TRIM(' ' FROM col)—— 显式指定空格字符和FROM关键字 -
TRIM(BOTH ' ' FROM col)在 2017 中不被支持,会语法错误 -
TRIM(LEADING ' ' FROM col)和TRIM(TRAILING ' ' FROM col)同样不支持,要等到 SQL Server 2022(兼容级别 160+)
为什么不用 LTRIM(RTRIM(col))?它更稳妥
虽然 TRIM(' ' FROM col) 在 2017+ 可用,但 RTRIM(LTRIM(col)) 仍是更推荐的写法,原因很实际:
- 它在 SQL Server 2005 起就存在,全版本兼容,连客户现场的 2008 R2 都能跑
- 语义清晰,无歧义,不会因版本升级或兼容级别变化而失效
- 执行计划几乎无差异,性能上没损失
- 避免团队里有人误写成
TRIM(col)导致上线失败
WHERE 条件里用 TRIM(' ' FROM col) = 'xxx' 会丢索引
哪怕字段 name 上建了索引,下面这句也必然触发全表扫描:
WHERE TRIM(' ' FROM name) = 'John'
因为函数作用于列后,B-Tree 索引无法匹配原始值。解决办法只有两个:
- 提前清洗:在
INSERT/UPDATE时就执行UPDATE t SET name = RTRIM(LTRIM(name)),并加约束或触发器防止回潮 - 建计算列索引(SQL Server 2016+):
ALTER TABLE t ADD name_clean AS RTRIM(LTRIM(name)); CREATE INDEX IX_name_clean ON t(name_clean);,之后查WHERE name_clean = 'John'
LTRIM/RTRIM 不处理制表符、换行符、全角空格
LTRIM() 和 RTRIM() 只认 ASCII 空格(CHAR(32)),对以下字符完全无效:
- 制表符
CHAR(9)(常见于 Excel 复制粘贴) - 换行符
CHAR(10)、回车符CHAR(13) - 中文全角空格
NCHAR(12288)
验证方法:
SELECT name, DATALENGTH(name), CAST(name AS VARBINARY(MAX)) FROM t WHERE name LIKE '%John%';
若看到类似 0x094A6F686E0A(含 0x09 或 0x0A),说明存在隐藏字符。真要清理,得手动嵌套 REPLACE():
REPLACE(REPLACE(REPLACE(RTRIM(LTRIM(col)), CHAR(9), ''), CHAR(10), ''), CHAR(13), '')
—— 这种写法丑但有效,比依赖 TRIM() 更贴近真实数据场景。

















