首页 > MySQL教程 > 正文

MySQL like查询字符转义遇到的坑

最近遇到一个问题, 在MySQL like查询时, 明明字符串时相同的, 但是却like不到结果, 后面经过多方面查找资料, 终于发现是字符串转义的问题, 而MySQL的LIKE的转义和普通字符串的不同。


首先来看一个测试:

mysql> SET @a='\\';SELECT @a,@a LIKE '\\\\';
 
+----+----------------+
| @a | @a LIKE '\\\\' |
+----+----------------+
| \  |              1 |
+----+----------------+

可以看出”\\\\“在LIKE中转义成”\“,LIKE的转义和平时用的字符串的转义还是有点不一样的。


查了下官方文档,对于转义字符的解释:


this is because the backslashes are stripped once by the parser and again when the pattern match is made,

leaving a single backslash to be matched against. 

mysql自己的parser转义一次,然后LIKE的pattern对前面的结果再转义一次。


也就是说上例中的“\\\\”第一次转义成“\\”,第二次才是“\”。


再来看个mysql字符转义的测试

mysql> SELECT '\%','\_';
+----+----+
| \% | \_ |
+----+----+
| \% | \_ |
+----+----+
1 row in set


呵呵,什么都转义(比如"\x" 转义成“x”,“\b"是回退字符),就是不转义”\%“和”\_“。而LIKE,都转义。恐怕MYSQL这样做的目的也是为了兼容LIKE吧。


总结下,LIKE转义字符串时,一共两次,第一次不转义”\%“和”\_“,第二次全部转义。转义的特殊字符可以参见 http://dev.mysql.com/doc/refman/5.1/en/string-literals.html#character-escape-sequences


LIKE的转义可以看成先替换“\\\\”为“\”,剩下的字符串用”\\“转义,剩下的字符串再用”\"转义。通常不遇见“\\”, LIKE的特殊解析是感觉不到的。


PHP版like特殊字符过滤

function likeEscape($str) {
    return strtr($str, array('%'=>'\\%', '_'=>'\\_', '\\'=>'\\\\\\\\'));
}

注意最后的双反斜杠转成了8个反斜杠, 其实就是1转4, 只不过在PHP字符串中需要转换一次, 这里有点绕,大家仔细想想,有问题可以留言


上一篇:mysql 的Escape转义字符串
下一篇:MySQL保留几位小数的4种方法

PythonTab微信公众号:

Python技术交流互助群 ( 请勿加多个群 ):

群1: 87464755

群2: 333646237

群3: 318130924

群4: 385100854