Message d'erreur sur MySql:
Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
J'ai parcouru plusieurs autres articles et je n'ai pas pu résoudre ce problème. La partie affectée est quelque chose de similaire à ceci:
CREATE TABLE users (
userID INT UNSIGNED NOT NULL AUTO_INCREMENT,
firstName VARCHAR(24) NOT NULL,
lastName VARCHAR(24) NOT NULL,
username VARCHAR(24) NOT NULL,
password VARCHAR(40) NOT NULL,
PRIMARY KEY (userid)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE TABLE products (
productID INT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(104) NOT NULL,
picturePath VARCHAR(104) NULL,
pictureThumb VARCHAR(104) NULL,
creationDate DATE NOT NULL,
closeDate DATE NULL,
deleteDate DATE NULL,
varPath VARCHAR(104) NULL,
isPublic TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (productID)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE TABLE productUsers (
productID INT UNSIGNED NOT NULL,
userID INT UNSIGNED NOT NULL,
permission VARCHAR(16) NOT NULL,
PRIMARY KEY (productID,userID),
FOREIGN KEY (productID) REFERENCES products (productID) ON DELETE RESTRICT ON UPDATE NO ACTION,
FOREIGN KEY (userID) REFERENCES users (userID) ON DELETE RESTRICT ON UPDATE NO ACTION
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
La procédure stockée que j'utilise est la suivante:
CREATE PROCEDURE updateProductUsers (IN rUsername VARCHAR(24),IN rProductID INT UNSIGNED,IN rPerm VARCHAR(16))
BEGIN
UPDATE productUsers
INNER JOIN users
ON productUsers.userID = users.userID
SET productUsers.permission = rPerm
WHERE users.username = rUsername
AND productUsers.productID = rProductID;
END
Je testais avec php, mais la même erreur est donnée avec SQLyog. J'ai également testé la recréation de l'ensemble de la base de données, mais sans rien de bon.
Toute aide sera très appréciée.
la source
COLLATE utf8_unicode_ci
des constantes de chaîne:SET @EMAIL = '[email protected]' COLLATE utf8_unicode_ci;
. C'est particulièrement utile si vous exécutez un script à partir d'une console, où l'encodage par défaut de la console s'applique au classement de vos constantes de chaîne.(utf8mb4_unicode_ci, IMPLICIT)
au lieu de(utf8_unicode_ci, IMPLICIT)
. Je racle des données sur le Web en utilisant python, puis je crée un fichier CSV avec les données grattées, que je traite ensuite avec un fichier PHP sur mon serveur qui télécharge les données dans ma base de données. toutes mes tables / colonnes MySQL sont classées commeutf8mb4_unicode_ci
. le problème peut-il se produire parce que j'encode les données commeutf8
en python / csv?J'ai passé une demi-journée à chercher des réponses à une erreur identique "Mélange illégal de collations" avec des conflits entre utf8_unicode_ci et utf8_general_ci.
J'ai trouvé que certaines colonnes de ma base de données n'étaient pas spécifiquement rassemblées utf8_unicode_ci . Il semble que mysql ait implicitement rassemblé ces colonnes utf8_general_ci .
Plus précisément, l'exécution d'une requête «SHOW CREATE TABLE table1» a généré quelque chose comme ce qui suit:
Notez que la ligne 'col1' varchar (4) CHARACTER SET utf8 NOT NULL n'a pas de classement spécifié. J'ai ensuite exécuté la requête suivante:
ALTER TABLE table1 CHANGE col1 col1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
Cela a résolu mon erreur "Mélange illégal de classements". J'espère que cela pourrait aider quelqu'un d'autre.
la source
COLLATE
pour la table entière (ieALTER TABLE table1 CHARSET utf8 COLLATE utf8_unicode_ci
) ne résoudra pas le problème , cela doit être fait pour chaque colonne (problématique).J'ai eu un problème similaire, mais cela m'est venu à l'esprit dans la procédure, lorsque mon paramètre de requête a été défini à l'aide de la variable, par exemple
SET @value='foo'
.La cause de ce problème était incompatible
collation_connection
avec le classement de la base de données. Changécollation_connection
pour correspondrecollation_database
et le problème a disparu. Je pense que c'est une approche plus élégante que d'ajouter COLLATE après param / value.Pour résumer: tous les classements doivent correspondre. Utilisation
SHOW VARIABLES
et assurez - vouscollation_connection
etcollation_database
match (vérifier également la collation de table à l' aideSHOW TABLE STATUS [table_name]
).la source
SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
Un peu similaire à la réponse @bpile, mon cas était un paramètre d'entrée my.cnf
collation-server = utf8_general_ci
. Après avoir réalisé cela (et après avoir tout essayé ci-dessus), j'ai basculé de force ma base de données sur utf8_general_ci au lieu de utf8_unicode_ci et c'était tout:la source
Dans mon propre cas, j'ai l'erreur suivante
Mélange illégal de classements (utf8_general_ci, IMPLICIT) et (utf8_unicode_ci, IMPLICIT) pour l'opération '='
Après des semaines de recherche sur Google, j'ai remarqué que les deux champs que je compare consistent en un nom de classement différent. Le premier c'est-à-dire le nom d'utilisateur est de utf8_general_ci tandis que le second est de utf8_unicode_ci donc je suis retourné à la structure de la deuxième table et j'ai changé le deuxième champ (matric_no) en utf8_general_ci et cela a fonctionné comme un charme.
la source
Malgré le fait d'avoir trouvé un nombre énorme de questions sur le même problème ( 1 , 2 , 3 , 4 ), je n'ai jamais trouvé de réponse tenant compte des performances, même ici.
Bien que plusieurs solutions de travail aient déjà été proposées, j'aimerais examiner les performances.
EDIT: Merci à Manatax pour avoir souligné que l'option 1 ne souffre pas de problèmes de performances.
L'utilisation des options
1 et2 , alias l' approche de conversion COLLATE , peut entraîner un goulot d'étranglement potentiel, car tout index défini sur la colonne ne sera pas utilisé, entraînant une analyse complète .Même si je n'ai pas essayé l' option 3 , je pense qu'elle subira les mêmes conséquences que l'option
1 et2.Enfin, l' option 4 est la meilleure option pour les très grandes tables lorsqu'elle est viable. Je veux dire qu'il n'y a aucune autre utilisation qui repose sur le classement d'origine.
Considérez cette requête simplifiée:
Dans mon exemple d'origine, j'ai eu beaucoup plus de jointures. Bien sûr, table1 et table2 ont des classements différents. Utilisation de l' assemblage opérateur d' pour effectuer un cast, entraînera la non-utilisation des index.
Voir l'explication SQL dans l'image ci-dessous.
Explication de la requête visuelle lors de l'utilisation de la distribution COLLATE
D'autre part, l' option 4 peut tirer parti des avantages de l'index possible et conduit à des requêtes rapides.
Dans l'image ci-dessous, vous pouvez voir la même requête en cours d'exécution après l'application de l' option 4 , c'est-à-dire en modifiant le classement schéma / table / colonne.
Explication de la requête visuelle après la modification du classement, et donc sans le cast de classement
En conclusion, si les performances sont importantes et que vous pouvez modifier le classement du tableau, optez pour l' option 4 . Si vous devez agir sur une seule colonne, vous pouvez utiliser quelque chose comme ceci:
la source
Cela se produit lorsqu'une colonne est explicitement définie sur un classement différent ou le classement par défaut est différent dans la table interrogée.
si vous avez de nombreuses tables pour lesquelles vous souhaitez modifier le classement, exécutez cette requête:
cela produira les requêtes nécessaires pour convertir toutes les tables pour utiliser le classement correct par colonne
la source