HEX()和encode()可暴露不可见字符,如CHAR(0)、制表符、不间断空格等,避免LENGTH()与CHAR_LENGTH()不一致导致的隐性问题,是排查数据污染最可靠手段。

用 HEX() 或 encode() 看原始字节,别信肉眼
SELECT 出来的字符串看着“干净”,不代表真干净。不可见字符(如 CHAR(0)、CHAR(9)、CHAR(160))在结果集里不显示,但会悄悄拉长 LENGTH()、破坏唯一性、导致 WHERE = 失效。
直接查十六进制最可靠:
- MySQL:
SELECT col, HEX(col) FROM t WHERE col LIKE '%abc%';—— 查到'00'就是CHAR(0),'09'是制表符,'A0'是不间断空格 - PostgreSQL:
SELECT col, encode(col::bytea, 'hex') FROM t;—— 同样看00、09、a0等字节序列 - SQL Server 不支持
HEX(),改用:SELECT col, CAST(col AS VARBINARY(MAX)) FROM t;
注意:HEX() 和 encode() 返回的是字节级表示,一个中文字符可能占 3 字节(UTF-8),别把多字节当多个控制符误判。
用 LENGTH() 和 CHAR_LENGTH() 对比找异常
如果 LENGTH(col) > CHAR_LENGTH(col),说明字段里混入了多字节字符——可能是 emoji、CJK 扩展字,也可能是隐藏控制符(尤其 CHAR(0) 在某些驱动下会被截断,造成长度错乱)。
这个对比特别适合批量筛问题列:
- MySQL/PostgreSQL:
SELECT * FROM t WHERE LENGTH(col) != CHAR_LENGTH(col); - SQL Server:
LEN()等价于CHAR_LENGTH(),不能用;得换DATALENGTH(col)(返回字节数)和LEN(col)(返回字符数)对比:WHERE DATALENGTH(col) > LEN(col) * 2(对nvarchar,单个字符最多 4 字节,但通常 2 字节起步)
这个方法快,但不精准:它抓出所有“字节≠字符”的情况,得配合 HEX() 进一步确认是不是真有不可见字符。
用正则快速匹配控制字符(MySQL 8.0+/PostgreSQL)
想直接捞出含不可见字符的行?别手写一堆 LIKE '%'+CHAR(9)+'%',用正则更省事:
- MySQL 8.0+:
SELECT * FROM t WHERE col REGEXP '[[:cntrl:]]|[u3000u00A0u200B]';——[[:cntrl:]]覆盖CHAR(0)–CHAR(31),后面补上常见 Unicode 空格 - PostgreSQL:
SELECT * FROM t WHERE col ~ E'[\x00-\x1f\u3000\u00a0\u200b]';—— 注意E''启用 Unicode 转义,\x00-\x1f匹配 ASCII 控制符 - SQL Server 没原生正则,只能靠循环或 CLR,不推荐线上扫表;退而求其次用
CHARINDEX()查单个字符:WHERE CHARINDEX(CHAR(0), col) > 0 OR CHARINDEX(CHAR(9), col) > 0
⚠️ 注意:CHAR(0) 在 SQL Server 的 CHARINDEX() 中被视作未定义字符,可能返回 0 即使存在——必须搭配 DATALENGTH() + SUBSTRING() + ASCII() 逐字节验证。
为什么不能只查首尾?中间也可能插着 CHAR(0)
很多人只检查 SUBSTRING(col, 1, 1) 和 SUBSTRING(col, LEN(col), 1),但 CHAR(0) 完全可能卡在第 5 位、第 12 位……一查就漏。
安全做法是用递归 CTE(SQL Server)或生成数字序列(MySQL 8.0+ numbers_table)逐位扫描:
- SQL Server 示例(查前 100 位):
WITH pos(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM pos WHERE n - MySQL 8.0+ 可用
ROW_NUMBER()配合 JSON_TABLE 模拟,但更简单是导出后用脚本处理——毕竟线上扫全表性能差,且ASCII()对多字节字符只取首字节,结果不可靠
真正要命的不是首尾空格,是中间那个看不见的 CHAR(0):它会让客户端解析 JSON 失败、ORM 映射截断、甚至触发某些数据库驱动的静默 bug。定位时,宁可慢一点,也要扫到位。

















