Mélange illégal de classements Erreur MySQL

124

J'obtiens cette étrange erreur lors du traitement d'un grand nombre de données ...

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 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

Que puis-je faire pour résoudre ce problème? Puis-je échapper à la chaîne d'une manière ou d'une autre pour que cette erreur ne se produise pas, ou dois-je changer le codage de ma table d'une manière ou d'une autre, et si oui, comment dois-je le changer?

Cliquez sur Upvote
la source
cette erreur, c'est un injectable ou pas?
hamza irizaj
1
Est-ce que cela répond à votre question? Erreur de mélange illégal de collations dans MySql
Farhan

Réponses:

288
SET collation_connection = 'utf8_general_ci';

puis pour vos bases de données

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 faufile parfois en suédois sans raison valable.

Ben Hughes
la source
3
@Ben: Merci pour une solution directement copiable. Cela m'a fait gagner beaucoup de temps.
Pistos
15
@Ben: Il a été initialement développé par une société suédoise ... C'est la raison derrière le réglage initial ennuyeux de latin1_swedish_ci .. :(
Vajk Hermecz
1
Je n'avais pas les autorisations pour faire la première déclaration mais cela fonctionnait simplement en faisant le tableau
Rob Sedgwick
Je t'aime pour ça! : P
prateekkathal
Il semble que cela fonctionne pour beaucoup de gens, mais malheureusement, j'ai toujours ce problème même après avoir essayé tous les appareils de ce fil. Le classement par défaut de ma base de données refuse obstinément de changer de 'ucs2_bin', donc j'ai même essayé de changer toutes les tables et le classement de connexion en 'usc2_bin' mais j'obtiens toujours l'erreur "Erreur SQL (1267): mélange illégal de classements (utf8_general_ci, IMPLICIT) et (ucs2_bin, IMPLICIT) pour l'opération '=' ".
bikeman868
15

Vous devez définir à la fois le codage de votre table et celui de la connexion sur UTF-8:

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

et

SET NAMES 'UTF8';
SET CHARACTER SET 'UTF8';
Quassnoi
la source
Les deux sont-ils nécessaires ou puis-je simplement faire l'un d'entre eux?
Cliquez sur Upvote le
ALTER DATABASE myDbDEFAULT CHARACTER SET utf8 COLLATE utf8_bin. Cela fonctionnerait-il? Ceci est fait pour que cela affecte toutes mes tables, pas seulement l'une d'entre elles
Cliquez sur Upvote le
1
ALTER DATABASE ne changera pas vos paramètres de table actuels, seulement ceux nouvellement créés. Cependant, cela ne fera pas de mal de modifier le jeu de caractères par défaut pour la base de données.
Quassnoi
SET NAMES et SET CHARACTER SET changeront le codage de votre connexion. Vous devez émettre ces commandes à chaque fois que vous vous connectez. Votre bibliothèque cliente peut prendre en charge une méthode plus élégante pour le faire (php :: mysqli le fait, php :: mysql ne le fait pas).
Quassnoi
Cela semble fonctionner pour le moment, j'accepterai après quelques tests supplémentaires. Les secondes requêtes doivent-elles être exécutées une fois ou au début de chaque script?
Cliquez sur Upvote le
13
CONVERT(column1 USING utf8)

Résout mon problème. Où colonne1 est la colonne qui me donne cette erreur.

Binaya Shrestha
la source
Pour moi, cela a fonctionné: CONVERT ("column1" USING LATIN1)
shasi kanth
4

Utilisez l'instruction suivante pour l'erreur

faites attention à vos données, prenez une sauvegarde si les données sont dans le tableau.

 ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
vpgodara
la source
2

En général, le meilleur moyen est de modifier le classement des tables. Cependant, j'ai une ancienne application et je ne suis pas vraiment en mesure d'estimer le résultat si cela a des effets secondaires. Par conséquent, j'ai essayé d'une manière ou d'une autre de convertir la chaîne dans un autre format qui a résolu le problème de classement. Ce que j'ai trouvé efficace, c'est de comparer les chaînes en convertissant les chaînes en une représentation hexadécimale de ses caractères. Sur la base de données cela se fait avec HEX(column).Pour PHP, vous pouvez utiliser cette fonction:

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);
}

Lorsque vous effectuez la requête de base de données, votre chaîne UTF8 d'origine doit d'abord être convertie en une chaîne iso (par exemple en utilisant utf8_decode()en PHP) avant de l'utiliser dans la base de données. En raison du type de classement, la base de données ne peut pas contenir de caractères UTF8, le comparisme devrait donc fonctionner même si cela modifie la chaîne d'origine (la conversion des caractères UTF8 qui n'existent pas dans le jeu de caractères ISO entraîne un? Ou ceux-ci sont entièrement supprimés). Assurez-vous simplement que lorsque vous écrivez des données dans la base de données, vous utilisez la même conversion UTF8 en ISO.

Stéphan
la source
2

J'ai créé ma table à l'origine avec CHARSET = latin1 . Après la conversion de table en utf8, certaines colonnes n'ont pas été converties, mais ce n'était pas vraiment évident. Vous pouvez essayer d'exécuter SHOW CREATE TABLE my_table;et voir quelle colonne n'a pas été convertie ou simplement corriger le jeu de caractères incorrect sur la colonne problématique avec la requête ci-dessous (modifiez la longueur de varchar et CHARSET et COLLATE selon vos besoins):

 ALTER TABLE `my_table` CHANGE `my_column` `my_column` VARCHAR(10) CHARSET utf8 
 COLLATE utf8_general_ci NULL;
Un Kunin
la source
2

Changer le jeu de caractères de la table en utf8

ALTER TABLE votre_nom_table CONVERT TO CHARACTER SET utf8

Jamsheer Mohammed
la source
0

Après avoir effectué vos corrections répertoriées dans la première réponse, modifiez les paramètres par défaut de votre serveur.

Dans votre " /etc/my.cnf.d/server.cnf " ou où qu'il se trouve, ajoutez les valeurs par défaut à la section [mysqld] pour qu'elle ressemble à ceci:

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

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

ITI
la source
0

J'ai trouvé que l'utilisation cast()était la meilleure solution pour moi:

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

Il y a aussi une convert()fonction. Plus de détails ici

Une autre ressource ici

Nitin Nanda
la source
0

Mon compte utilisateur n'avait pas les autorisations pour modifier la base de données et la table, comme suggéré dans cette solution .

Si, comme moi, vous ne vous souciez pas du classement des caractères (vous utilisez l'opérateur '='), vous pouvez appliquer le correctif inverse. Exécutez ceci avant votre SELECT:

SET collation_connection = 'latin1_swedish_ci';
pyb
la source