like中下划线和百分号是通配符而非字面字符,需用escape指定转义符(如''或'!')并双重转义转义符自身;跨库建议选'$'等无歧义字符,复杂模式宜用正则。

LIKE 中的下划线和百分号为什么总是匹配错
因为 _ 和 % 是 LIKE 的通配符,不是字面字符。比如想查用户名以 "A_B" 开头的记录,写成 WHERE username LIKE 'A_B%',实际会匹配 "AxB"、"AyB" 等任意单字符,而不是字面的 "A_B"。
解决方法是用 ESCAPE 指定转义字符,再对通配符本身加转义。常见做法是选 或 ! 作转义符:
-
WHERE username LIKE 'A_B%' ESCAPE ''—— 用反斜杠转义下划线 -
WHERE username LIKE 'A!_B%' ESCAPE '!'—— 用叹号转义,避免 Windows 路径中反斜杠被二次解析
ESCAPE 字符本身出现在字符串里怎么办
如果选的转义符(比如 )恰好是你想搜索的字面内容,它自己也得被转义。例如:查包含 "path oile" 的路径字段,又用 做 ESCAPE 字符,那每个 都要写成 \:
WHERE path LIKE '%path\to\file%' ESCAPE ''
注意:ESCAPE 后面只接受单个字符,不能写 ESCAPE '\' ;且不同数据库对反斜杠处理略有差异——MySQL 默认启用 NO_BACKSLASH_ESCAPES 模式时, 不再是默认转义符,必须显式声明 ESCAPE 才生效。
不同数据库对 ESCAPE 的兼容性差异
标准 SQL 支持 ESCAPE,但细节不统一:
- PostgreSQL:严格遵循标准,
ESCAPE必须是单字符,支持任意 ASCII 可见字符(如'$'、'|') - SQL Server:支持
ESCAPE,但若未指定,部分旧版本会把当默认转义符(不可靠,务必显式写) - SQLite:支持
ESCAPE,但不支持空格或控制字符作转义符 - Oracle:允许
ESCAPE,且可省略引号(ESCAPE ''和ESCAPE ''都行),但建议加引号保持可读性
跨库迁移时,别假设 总是有效;优先选无歧义字符如 '$',并始终显式声明 ESCAPE 子句。
用正则替代 LIKE 是否更可靠
当模式复杂(比如“以 A 开头、中间有且仅有一个下划线、后跟数字”),LIKE 很难表达,这时该换正则:
- PostgreSQL:用
~操作符,WHERE username ~ '^A_[0-9]+$' - MySQL 8.0+:用
REGEXP,WHERE username REGEXP '^A_[0-9]+$' - SQL Server:没有原生正则,得用
LIKE组合或 CLR 函数,或升级到 Azure SQL 支持STRING_SPLIT+ 模式预处理
但正则性能通常比 LIKE 差,尤其没索引支持时;简单字面+通配需求,坚持用 LIKE + ESCAPE 更稳。
真正容易被忽略的是:很多 ORM(如 SQLAlchemy、MyBatis)会自动转义传入的 LIKE 参数,但不会帮你处理 ESCAPE 字符——你得手动在 SQL 片段里补上 ESCAPE 子句,否则转义失效。










