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

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

首先来看一个测试:

1

2

3

4

5

6

7

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字符转义的测试

1

2

3

4

5

6

7

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特殊字符过滤

1

2

3

function likeEscape($str) {

    return strtr($strarray('%'=>'\%''_'=>'\_''\'=>'\\\\'));

}

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

发布了29 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/HAOXUAN168/article/details/104087348