2011-12-20 20 views
5

Está frustrado con el escape de patrón de MySQL usado en el operador LIKE.Operador de MySQL LIKE con comodín y barra diagonal inversa

[email protected]> create table foo(name varchar(255)); 
Query OK, 0 rows affected (0.02 sec) 

[email protected]> insert into foo values('with\\slash'); 
Query OK, 1 row affected (0.00 sec) 

[email protected]> insert into foo values('\\slash'); 
Query OK, 1 row affected (0.00 sec) 

[email protected]> select * from foo where name like '%\\\\%'; 
Empty set (0.01 sec) 

[email protected]> select * from foo; 
+------------+ 
| name  | 
+------------+ 
| with\slash | 
| \slash  | 
+------------+ 
2 rows in set (0.00 sec) 

[email protected]> select * from foo where name like '%\\\\%'; 
Empty set (0.00 sec) 

[email protected]> select * from foo where name like binary '%\\\\%'; 
+------------+ 
| name  | 
+------------+ 
| with\slash | 
| \slash  | 
+------------+ 
2 rows in set (0.00 sec) 

De acuerdo con documentos de MySQL: http://dev.mysql.com/doc/refman/5.5/en/string-comparison-functions.html#operator_like %\\\\% es el operando de la derecha, pero ¿por qué no da resultado?

EDITAR: La base de datos que estoy probando en tiene character_set_database establecido en utf8. Para ampliar mi investigación, creé la misma configuración en una base de datos que tiene character_set_database establecida en latin1, y adivinen qué, '%\\\\%' funciona.

EDITAR: El problema se puede reproducir y es el problema de intercalación de campo. Detalles: http://bugs.mysql.com/bug.php?id=63829

+0

Cuando uso sus comandos exactamente, 'select * from foo donde name like '% \\\\%';' funciona para mí. Aunque no entiendo por qué no funciona para ti, tengo curiosidad por saberlo. –

+0

Puede tener algo que ver con el juego de caracteres de la base de datos. Actualicé la publicación original. – EnToutCas

+0

Compruebe esto: - 'select @@ session.sql_mode; select @@ global.sql_mode; ' – ajreal

Respuesta

0

Parece que tiene alguna relación con ese error de MySQL: http://bugs.mysql.com/bug.php?id=46659

Creo que se conecta a MySQL no especificar --character-set-server opción correcta (que por defecto es latin1 con intercalación latin1_swedish_ci), y teniendo utf-8 como el actual juego de caracteres de la consola. Esto provoca conversiones y comparaciones de caracteres incorrectos cuando se trata de datos que se supone que se convertirán al utf8 del juego de caracteres --character-set-server.

2

En MySQL 5.6.10, con la intercalación campo de texto utf8mb4_unicode_520_ci esto se puede lograr mediante el uso de 5 caracteres de barra invertida en lugar de 4, es decir:

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

De alguna manera, contra todas las expectativas, esto encuentra correctamente todas las filas con barras diagonales inversas. Al menos esto debería funcionar hasta que se solucione el error de clasificación de campo de MySQL anterior. Teniendo en cuenta que han pasado más de 5 años desde que se descubrió el error, cualquier aplicación diseñada con esto puede sobrevivir a su utilidad incluso antes de que se solucione MySQL, por lo que debería ser una solución bastante confiable.

0

Con MySQL 5.0.12 dev en Windows 10 que tiene los siguientes resultados cuando cambié la consulta de

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

a

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

funciona y sin embargo la primera cadena con barras diagonales era el contenido original del campo. Parece haber interpretado barras diagonales como barras diagonales inversas.

Cuestiones relacionadas