带有通配符和反斜杠的MySQL LIKE运算符

时间:2011-12-20 23:06:22

标签: mysql escaping wildcard

对LIKE运算符中使用的MySQL模式转义感到沮丧。

root@dev> create table foo(name varchar(255));
Query OK, 0 rows affected (0.02 sec)

root@dev> insert into foo values('with\\slash');
Query OK, 1 row affected (0.00 sec)

root@dev> insert into foo values('\\slash');
Query OK, 1 row affected (0.00 sec)

root@dev> select * from foo where name like '%\\\\%';
Empty set (0.01 sec)

root@dev> select * from foo;
+------------+
| name       |
+------------+
| with\slash | 
| \slash     | 
+------------+
2 rows in set (0.00 sec)

root@dev> select * from foo where name like '%\\\\%';
Empty set (0.00 sec)

root@dev> select * from foo where name like binary '%\\\\%';
+------------+
| name       |
+------------+
| with\slash | 
| \slash     | 
+------------+
2 rows in set (0.00 sec)

根据MySQL文档:http://dev.mysql.com/doc/refman/5.5/en/string-comparison-functions.html#operator_like %\\\\%是正确的操作数,但为什么它没有产生结果呢?

编辑: 我正在测试的数据库中将character_set_database设置为utf8。为了进一步调查,我在character_set_database设置为latin1的数据库中创建了相同的设置,猜猜是什么,'%\\\\%'有效!

编辑: 问题可以重现,这是现场整理问题。详情:http://bugs.mysql.com/bug.php?id=63829

3 个答案:

答案 0 :(得分:2)

在MySQL 5.6.10中,使用文本字段collat​​ion utf8mb4_unicode_520_ci这可以通过使用5个反斜杠字符而不是4来实现,即:

select * from foo where name like binary '%\\\\\%';

不知何故,出乎所有人的意料,这会正确地找到带有反斜杠的所有行。 至少这应该工作,直到修复上面的MySQL字段整理错误。考虑到自从发现错误已超过5年,任何使用此设计的应用程序可能会在MySQL被修复之前比其实用性更长 - 所以应该是一个非常可靠的解决方法。

答案 1 :(得分:1)

在Windows 10上使用MySQL 5.0.12 dev时,当我从

更改查询时,我得到了以下结果
SELECT * FROM `foo` WHERE `name` LIKE '%http:\/\/%'

SELECT * FROM `foo` WHERE `name` LIKE '%http:\\\\\\\%'

它有效,但带有正斜杠的第一个字符串是原始字段内容。它似乎已将正斜杠解释为反斜杠。

答案 2 :(得分:0)

它似乎与MySQL错误有关:http://bugs.mysql.com/bug.php?id=46659

我认为您连接到mysql时没有指定正确的--character-set-server选项(默认为latin1并使用排序规则latin1_swedish_ci),并且utf-8作为控制台的当前字符集。当您处理应该从--character-set-server的字符集转换为utf8的数据时,这会导致错误的字符转换和比较。