对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
答案 0 :(得分:2)
在MySQL 5.6.10中,使用文本字段collation 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的数据时,这会导致错误的字符转换和比较。