trim默认仅移除ascii空格(u+0020),对制表符、换行符、全角空格等不可见字符无效;各数据库语法差异大,postgresql需显式写trim(both from col),mysql支持trim(col),sql server 2017+才支持trim(),旧版须用ltrim(rtrim(col))。

TRIM 默认只认 ASCII 空格(U+0020)
绝大多数数据库的 TRIM() 函数在不指定字符时,仅识别并移除 ASCII 空格(十进制 32,十六进制 20)。它对制表符( ,U+0009)、换行符(
,U+000A)、回车符(
,U+000D)、全角空格( ,U+3000)、不间断空格( ,U+00A0)或零宽空格(U+200B)完全无感。
常见错误现象:SELECT TRIM(' hello world
') 在 PostgreSQL 或 MySQL 中返回原样字符串,因为首尾的全角空格和换行符不在默认处理范围内。
- 验证方法:用
HEX(col)或ENCODE(col::bytea, 'hex')查看真实字节,比如HEX(' ')返回e38080(U+3000),而HEX(' ')是20 - MySQL 5.7 及更早版本甚至不支持
TRIM(col)简写,必须写成TRIM(BOTH ' ' FROM col),否则报错 - Oracle 的
TRIM()不接受省略FROM的写法,TRIM(' ' FROM col)才合法,TRIM(col)会报错
想删 tab、换行、全角空格?得靠正则或 REPLACE
标准 SQL 没有“一键清所有空白”的 TRIM() 变体。必须组合函数或使用方言能力:
- PostgreSQL:用
REGEXP_REPLACE(col, E'^[\s\u3000]+|[\s\u3000]+$', '', 'g')—— 注意E''表示转义字符串,\s匹配 Unicode 空白,\u3000显式补全角空格 - MySQL 8.0+:
REGEXP_REPLACE(col, '[[:space:]]|\u3000', ''),但注意这会删所有空白(含中间),如需仅首尾,得写REGEXP_REPLACE(col, '^[[:space:]]+|[[:space:]]+$', '') - SQL Server(2016+):只能多层
REPLACE(),例如REPLACE(REPLACE(REPLACE(col, CHAR(9), ''), CHAR(10), ''), N' ', '');CHAR(9)是 tab,N' '是全角空格 - SQLite:无正则,只能嵌套
REPLACE(),且不支持 Unicode 字符直接写入字符串字面量,需用 hex 编码或外部处理
WHERE 里用 TRIM 容易让索引失效
执行 WHERE TRIM(name) = 'John' 时,数据库无法利用 name 字段上的普通 B-Tree 索引,因为函数改变了原始值分布。结果通常是全表扫描,数据量一过百万就明显卡顿。
- 安全做法:清洗写入时就做,即
INSERT INTO t (name) VALUES (TRIM(?)) - MySQL 8.0+ 支持函数索引:
CREATE INDEX idx_name_trim ON t ((TRIM(name))),但查询必须严格匹配该表达式,WHERE TRIM(name) = 'John'才能命中 - SQL Server 可建计算列:
ALTER TABLE t ADD name_trim AS TRIM(name),再对name_trim建索引 -
TRIM(NULL)返回NULL,所以UPDATE t SET col = TRIM(col)不会影响 NULL 值——这点常被忽略,导致误以为清洗没生效
不同数据库对 “BOTH” “LEADING” 的支持程度不一
SQL Server 2022 才正式支持 TRIM(LEADING 'x' FROM col) 这类写法,且需数据库兼容级别 ≥ 160;PostgreSQL 要求显式写 TRIM(BOTH FROM col),省略 BOTH 直接报错;MySQL 则允许 TRIM(LEADING FROM col),但不支持多字符同时指定(如 TRIM('
' FROM col) 会报错)。
- MySQL 中
TRIM(BOTH ' ' FROM col)只删空格和 tab,但顺序无关,' '效果一样 - PostgreSQL 不支持多字符列表,
TRIM(BOTH ' ' FROM col)会被当作单个字符串字面量处理,实际只删开头结尾是否等于' '这个整体 - Oracle 对
TRIM()的字符参数长度限制严格,超长会截断或报错,建议优先用REGEXP_REPLACE
TRIM()。得先用 HEX() 或 LENGTH() 对比确认空白类型,再按数据库能力选正则、多层 REPLACE 或计算列索引——否则看似删了空格,= 查询还是不匹配。










