%和_在like中是通配符,直接使用会导致字面值被误解析为模式;必须用escape子句指定转义字符(如'!'或'')并显式转义,且转义需覆盖所有出现位置,否则匹配结果错误。

LIKE语句里%和_为什么不能直接用
因为%和_在LIKE中是通配符:%匹配任意长度字符串,_匹配单个字符。如果你查的字段里真存了%或_(比如用户输入的折扣码"50%off"或用户名"user_name"),不转义就会被当成模式去匹配,结果完全不对。
用ESCAPE指定转义字符是最可靠的方法
标准SQL支持ESCAPE子句,你选一个不会出现在目标数据里的字符(比如、!或|),然后在要转义的%或_前面加它。数据库会把那个组合识别为字面量。
常见写法示例:
SELECT * FROM products WHERE name LIKE '%50%off%' ESCAPE ''; SELECT * FROM users WHERE username LIKE 'user_name' ESCAPE '';
注意:ESCAPE必须紧跟LIKE表达式之后,且只对当前LIKE生效。
- 别用
ESCAPE ''(空字符串)——多数数据库报错或行为未定义 - 如果选的转义字符本身可能出现在数据里(比如用
/但字段存了路径"a/b/c"),就得换一个 - PostgreSQL默认不认
为转义符,得显式写ESCAPE ''才生效
不同数据库对默认转义符的支持差异大
MySQL允许在字符串里用\%表示字面%,但这依赖sql_mode是否含NO_BACKSLASH_ESCAPES;SQL Server默认用ESCAPE,不支持反斜杠隐式转义;Oracle则严格要求ESCAPE子句。靠“默认行为”写法容易跨库出错。
- MySQL 8.0+ 在严格模式下,
'50%'会被当作语法错误,必须用ESCAPE - SQLite默认不支持
ESCAPE,得用PRAGMA case_sensitive_like = ON配合LIKE的字面匹配逻辑绕过,但不可靠 - 参数化查询(如
WHERE name LIKE ?)里,转义必须在应用层完成,不能指望驱动自动处理
实际查含%或_的数据时,最容易漏掉的点
不是忘了转义,而是忘了所有出现位置都要处理:开头、中间、结尾、连续多个。比如查"report_v2.1%",里面的%要转,但.和1不用;而"a_b_c"里两个_都得转。
- 动态拼接SQL时,用
REPLACE预处理值:MySQL用REPLACE(?, '_', '_')再拼进LIKE,但记得同步加ESCAPE '' - 用正则替代
LIKE(如PostgreSQL的~操作符)可避开转义问题,但失去索引优化能力 - 如果字段值固定含
%(如状态码"DONE%"),考虑改用=或IN,比LIKE更安全高效
真正麻烦的是模糊匹配里混着真实通配符和字面通配符——比如搜索“以abc开头、中间有_、结尾是%的字符串”,这时候每个符号的语义必须人工厘清,ESCAPE只是工具,逻辑得自己兜住。










