Normalizar los caracteres acentuados en las consultas de MySQL.
utf-8 diacritics (4)
Me gustaría poder hacer consultas que normalicen los caracteres acentuados, por ejemplo:
é, è, and ê
todos se tratan como ''e'', en las consultas que usan ''='' y ''como''. Tengo una fila con el campo de nombre de usuario configurado en '' rené '', y me gustaría poder hacer coincidir con '' rene '' y '' rené ''.
Estoy intentando hacer esto con la cláusula de ''compaginación'' en MySQL 5.0.8. Obtuve el siguiente error:
mysql> select * from User where username = ''rené'' collate utf8_general_ci;
ERROR 1253 (42000): COLLATION ''utf8_general_ci'' is not valid for CHARACTER SET ''latin1''
FWIW, mi tabla fue creada con:
CREATE TABLE `User` (
`id` bigint(19) NOT NULL auto_increment,
`username` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniqueUsername` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=56790 DEFAULT CHARSET=utf8
El motivo del error no es la tabla sino el conjunto de caracteres de su entrada, es decir, el ''rené'' en su consulta. El comportamiento depende de la variable character_set_connection :
El conjunto de caracteres utilizado para literales que no tienen un introductor de conjunto de caracteres y para la conversión de número a cadena.
Usando el cliente MySQL, cámbielo usando SET NAMES
:
Una sentencia SET NAMES ''charset_name'' es equivalente a estas tres afirmaciones:
SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;
(de http://dev.mysql.com/doc/refman/5.5/en/charset-connection.html )
Ejemplo de salida:
mysql> set names latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from User where username = ''rené'' collate utf8_general_ci;
ERROR 1253 (42000): COLLATION ''utf8_general_ci'' is not valid for CHARACTER SET ''latin1''
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from User where username = ''rené'' collate utf8_general_ci;
Empty set (0.00 sec)
Alternativamente, el uso puede establecer explícitamente el conjunto de caracteres utilizando un ''introductor de conjunto de caracteres'':
mysql> set names latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from User where username = _utf8''rené'' collate utf8_general_ci;
Empty set (0.00 sec)
Sé que esta pregunta es bastante antigua, pero como Google me llevó aquí para una pregunta relacionada, creo que todavía merece una respuesta :)
He implementado un comando strtr php function / tr unix en MySQL. Puede obtener el código fuente here
Se puede utilizar como:
SELECT tr(name, ''áäèëî'', ''aaeei'') FROM persons
o para despojar a algunos personajes
SELECT tr(name, ''áäèëî'', null) FROM persons
Le sugiero que guarde las versiones normalizadas en su tabla además con el nombre de usuario real. Cambiar la codificación sobre la marcha puede ser costoso, y debe realizar la conversión nuevamente para cada fila en cada búsqueda.
Si está utilizando PHP, puede usar iconv() para manejar la conversión:
$username = ''rené'';
$normalized = iconv(''UTF-8'', ''ASCII//TRANSLIT'', $string);
Luego simplemente guardaría ambas versiones y usaría la versión normalizada para buscar y el nombre de usuario normal para mostrar. La comparación y la selección serán mucho más rápidas desde la columna normalizada, siempre que también normalice la cadena de búsqueda:
$search = mysql_real_escape_string(iconv(''UTF-8'', ''ASCII//TRANSLIT'', $_GET[''search'']));
mysql_query("SELECT * FROM User WHERE normalized LIKE ''%".$search."%''");
Por supuesto, este método podría no ser viable si tiene varias columnas que necesitan normalizaciones, pero en su caso específico, esto podría funcionar bien.
$normalized = iconv(''UTF-8'', ''ASCII//TRANSLIT'', $string);
¿Es una solución php perfecta, pero en mysql? ¿CONVERTIR?
en mysql
SELECT ''Álvaro José'' as accented, (CONVERT (''Álvaro José'' USING ascii)) as notaccented
Produce:
Álvaro José ?lvaro Jos?
Las palabras acentuadas no se convierten en palabras sin acento, no es equivalente a un translit de iconv.
RegExp no funciona con UTF-8.
No hay ninguna solución.