200 votes

Comment réparer Incorrecte "chaîne de valeur" des erreurs?

Après avoir remarqué une application tendance à jeter aléatoire e-mails suite à une erreur de la chaîne de valeur des erreurs, je suis allé, bien que de commutation de plusieurs colonnes de texte à utiliser l' utf8 colonne jeu de caractères et la valeur par défaut de la colonne collate (utf8_general_ci) alors qu'elle allait accepter. Ce corrigé la plupart des erreurs, et en a fait la demande cessez de recevoir des erreurs sql quand il a frappé non latine e-mails, trop.

Malgré cela, certains des e-mails sont toujours provoque le programme pour frapper incorrecte de la chaîne de valeur errrors: (Incorrect string value: '\xE4\xC5\xCC\xC9\xD3\xD8...' for column 'contents' at row 1)

Le contenu de la colonne est une MEDIUMTEXT datatybe qui utilise l' utf8 colonne charset et l' utf8_general_ci colonne rassembler. Il n'y a pas de drapeaux que je peux activer dans cette colonne.

En gardant à l'esprit que je ne veux pas toucher ou même de regarder le code source de l'application, sauf si absolument nécessaire:

  • Quelle est la cause de cette erreur? (oui, je sais que les e-mails sont plein d'aléatoire d'ordures, mais j'ai pensé utf8 serait assez permissive)
  • Comment puis-je résoudre ce problème?
  • Quels sont les effets probables d'une telle solution?

Une chose que je considère a été le passage à une utf8 varchar([un grand nombre]) avec le binaire indicateur allumé, mais je suis assez familier avec MySQL, et n'ai aucune idée si cette correction fait sens.

162voto

nico gawenda Points 962

Je ne voudrais pas suggérer Richies réponse, parce que vous êtes le vissage des données à l'intérieur de la base de données. Vous ne serait pas résoudre le problème, mais d'essayer de "cacher" et de ne pas être en mesure d'effectuer l'essentiel de la base de données des opérations avec la chié de données.

Si vous rencontrez cette erreur soit les données que vous envoyez n'est pas codé en UTF-8, ou votre connexion n'est pas UTF-8. Tout d'abord, vérifiez que la source de données (un fichier, ...) vraiment est UTF-8.

Ensuite, vérifiez votre connexion de base de données, vous devez le faire après la connexion:

SET NAMES 'utf8';
SET CHARACTER SET utf8;

Ensuite, vérifiez que les tables où sont stockées les données ont le jeu de caractères utf8:

SELECT
  `tables`.`TABLE_NAME`,
  `collations`.`character_set_name`
FROM
  `information_schema`.`TABLES` AS `tables`,
  `information_schema`.`COLLATION_CHARACTER_SET_APPLICABILITY` AS `collations`
WHERE
  `tables`.`table_schema` = DATABASE()
  AND `collations`.`collation_name` = `tables`.`table_collation`
;

Enfin, vérifiez vos paramètres de base de données:

mysql> show variables like '%colla%';
mysql> show variables like '%charac%';

Si la source, le transport et la destination sont en UTF-8, votre problème est parti;)

89voto

moeffju Points 1627

MySQL en utf-8 types ne sont pas réellement correcte utf-8 – il n'utilise jusqu'à trois octets par caractère et ne supporte que le Plan Multilingue de Base (c'est à dire pas de Emoji, pas de plan astral, etc.).

Si vous avez besoin de stocker des valeurs de la hausse de l'Unicode des avions, vous avez besoin de la utf8mb4 encodages.

43voto

RichieHindle Points 98544

"\xE4\xC5\xCC\xC9\xD3\xD8" n'est pas valide UTF-8. Testé à l'aide de Python:

>>> "\xE4\xC5\xCC\xC9\xD3\xD8".decode("utf-8")
...
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data

Si vous êtes à la recherche d'un moyen d'éviter des erreurs de décodage dans la base de données, le cp1252 encodage (aka "Windows-1252" aka "les Fenêtres de l'europe Occidentale") est la plus permissive le codage n'est - chaque octet de la valeur est valide d'un point de code.

Bien sûr, il ne va pas comprendre la véritable UTF-8, ni de toute autre non-cp1252 encodage, mais il semble que vous n'êtes pas trop intéressé à ce sujet?

31voto

frankshaka Points 101

J'ai résolu ce problème, aujourd'hui, en modifiant la colonne 'LONGBLOB' type qui stocke les octets brutes au lieu de caractères UTF-8.

Le seul inconvénient est que vous devez prendre soin de l'encodage vous-même. Si un client de votre application utilise l'encodage UTF-8 et l'autre utilise CP1252, vous pouvez avoir vos e-mails envoyés avec des caractères incorrects. Pour éviter cela, utilisez toujours le même encodage (par exemple UTF-8) sur l'ensemble de vos applications.

Reportez-vous à cette page http://dev.mysql.com/doc/refman/5.0/en/blob.html pour plus de détails sur les différences entre le TEXTE/LONGTEXT et BLOB/LONGBLOB. Il y a aussi beaucoup d'autres arguments sur le web discuter de ces deux.

8voto

Ondra Žižka Points 8262

En général, cela se produit lorsque vous insérez des chaînes de colonnes incompatible avec l'encodage/classement.

J'ai eu cette erreur quand j'ai eu des Déclencheurs, qui héritent de classement du serveur pour une raison quelconque. Et mysql par défaut est (au moins sur Ubuntu) latin-1 avec les suédois de classement. Même si j'ai eu de la base de données et toutes les tables de jeu en UTF-8, je n'avais pas encore fixé my.cnf:

/etc/mysql/my.cnf :

[mysqld]
character-set-server=utf8
default-character-set=utf8

Et ce doit établir la liste de tous les déclencheurs avec l'utf8-*:

select TRIGGER_SCHEMA, TRIGGER_NAME, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, DATABASE_COLLATION from information_schema.TRIGGERS

Et certaines des variables énumérées par ce devrait également avoir utf-8-* (pas le latin-1 ou un autre encodage):

show variables like 'char%';

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X