Mezcla ilegal de intercalaciones Error de MySQL


124

Recibo este extraño error al procesar una gran cantidad de datos ...

Error Number: 1267

Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='

SELECT COUNT(*) as num from keywords WHERE campaignId='12' AND LCASE(keyword)='hello again 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

¿Qué puedo hacer para resolver esto? ¿Puedo escapar de la cadena de alguna manera para que no se produzca este error, o necesito cambiar la codificación de mi tabla de alguna manera, y si es así, a qué debo cambiarla?


este error, es un inyectable o no?
hamza irizaj

Respuestas:


288
SET collation_connection = 'utf8_general_ci';

luego para tus bases de datos

ALTER DATABASE your_database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

MySQL se cuela sueco allí a veces sin ninguna razón sensata.


3
@Ben: Gracias por una solución que se puede copiar directamente. Me ahorró mucho tiempo.
Pistos

15
@Ben: Inicialmente fue desarrollado por una empresa sueca ... Esa es la razón detrás del molesto ajuste inicial latin1_swedish_ci ... :(
Vajk Hermecz

1
No tenía permisos para hacer la primera declaración, pero funcionó simplemente haciendo la tabla
Rob Sedgwick

¡Te amo por esto! : P
prateekkathal

Parece que esto funciona para mucha gente, pero desafortunadamente todavía tengo este problema incluso después de probar todo el dispositivo en este hilo. La intercalación predeterminada de mi base de datos se niega obstinadamente a cambiar de 'ucs2_bin', así que incluso intenté cambiar todas las tablas y la intercalación de conexión a 'usc2_bin' pero sigo recibiendo el error "Error SQL (1267): mezcla ilegal de intercalaciones (utf8_general_ci, IMPLICIT) y (ucs2_bin, IMPLICIT) para la operación '=' ".
bikeman868

15

Debe configurar tanto la codificación de la tabla como la codificación de la conexión en UTF-8:

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

y

SET NAMES 'UTF8';
SET CHARACTER SET 'UTF8';

¿Son necesarios ambos o puedo hacer solo uno de ellos?
Haga clic en Upvote

ALTERAR myDbEL CONJUNTO DE CARACTERES POR DEFECTO DE LA BASE DE DATOS utf8 COLLATE utf8_bin. Funcionaría eso? Esto se hace para que afecte a todas mis tablas, no solo a una de ellas
Haga clic en Upvote

1
ALTER DATABASE no cambiará la configuración actual de la tabla, solo las recién creadas. Aunque no estará de más alterar el juego de caracteres predeterminado para la base de datos también.
Quassnoi

SET NAMES y SET CHARACTER SET cambiarán la codificación de su conexión. Debe emitir estos comandos cada vez que se conecte. Su biblioteca cliente puede admitir un método más elegante para hacerlo (php :: mysqli lo hace, php :: mysql no lo hace).
Quassnoi

Parece que funciona por ahora, lo aceptaré después de algunas pruebas más. ¿Es necesario ejecutar las segundas consultas una vez o al comienzo de cada secuencia de comandos?
Haga clic en Upvote

13
CONVERT(column1 USING utf8)

Resuelve mi problema. Donde column1 es la columna que me da este error.


Para mí, esto funcionó: CONVERT ("column1" USING LATIN1)
shasi kanth

4

Utilice la siguiente declaración para el error

Tenga cuidado con la copia de seguridad de sus datos si los datos están en la tabla.

 ALTER TABLE your_table_name CONVERTIR A CHARACTER SET utf8 COLLATE utf8_general_ci;

2

En general, la mejor forma es cambiar la clasificación de la tabla. Sin embargo, tengo una aplicación antigua y realmente no puedo estimar el resultado si esto tiene efectos secundarios. Por lo tanto, intenté de alguna manera convertir la cadena en algún otro formato que resolviera el problema de clasificación. Lo que encontré funcionando es comparar cadenas convirtiendo las cadenas en una representación hexadecimal de sus caracteres. En la base de datos, esto se hace con HEX(column).Para PHP, puede usar esta función:

public static function strToHex($string)
{
    $hex = '';
    for ($i=0; $i<strlen($string); $i++){
        $ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
    return strToUpper($hex);
}

Al realizar la consulta de la base de datos, su cadena UTF8 original debe convertirse primero en una cadena iso (por ejemplo, usarla utf8_decode()en PHP) antes de usarla en la base de datos. Debido al tipo de intercalación, la base de datos no puede tener caracteres UTF8 dentro, por lo que la comparación debería funcionar aunque esto cambie la cadena original (la conversión de caracteres UTF8 que no existen en el conjunto de caracteres ISO da como resultado un? O estos se eliminan por completo). Solo asegúrese de que cuando escriba datos en la base de datos, utilice la misma conversión de UTF8 a ISO.


2

Tenía mi tabla creada originalmente con CHARSET = latin1 . Después de la conversión de la tabla a utf8, algunas columnas no se convirtieron, sin embargo, eso no fue realmente obvio. Puede intentar ejecutar SHOW CREATE TABLE my_table;y ver qué columna no se convirtió o simplemente corregir el juego de caracteres incorrecto en la columna problemática con la consulta a continuación (cambie la longitud de varchar y CHARSET y COLLATE según sus necesidades):

 ALTER TABLE `my_table` CHANGE `my_column` `my_column` VARCHAR(10) CHARSET utf8 
 COLLATE utf8_general_ci NULL;

2

Cambie el juego de caracteres de la tabla a utf8

ALTER TABLE your_table_name CONVERTIR A CONJUNTO DE CARACTERES utf8


0

Después de realizar las correcciones enumeradas en la respuesta principal, cambie la configuración predeterminada de su servidor.

En su " /etc/my.cnf.d/server.cnf " o donde sea que esté ubicado, agregue los valores predeterminados a la sección [mysqld] para que se vea así:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

Fuente: https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html


0

Descubrí que usar cast()era la mejor solución para mí:

cast(Format(amount, "Standard") AS CHAR CHARACTER SET utf8) AS Amount

También hay una convert()función. Más detalles aquí

Otro recurso aquí


0

Mi cuenta de usuario no tenía los permisos para modificar la base de datos y la tabla, como se sugiere en esta solución .

Si, como yo, no le importa la intercalación de caracteres (está utilizando el operador '='), puede aplicar la corrección inversa. Ejecute esto antes de su SELECT:

SET collation_connection = 'latin1_swedish_ci';
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.