«Valeur de chaîne incorrecte» en essayant d’insérer UTF-8 dans MySQL via JDBC?

Voici comment ma connexion est définie:
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);

Et j’obtiens l’erreur suivante lorsque vous ajoutez une ligne à une table:
Incorrect ssortingng value: '\xF0\x90\x8D\x83\xF0\x90...' for column 'content' at row 1

J’insère des milliers d’enregistrements et j’obtiens toujours cette erreur lorsque le texte contient \ xF0 (la valeur de chaîne incorrecte commence toujours par \ xF0).

Le classement de la colonne est utf8_general_ci.

Quel pourrait être le problème?

MySQL utf8 ne permet que les caractères Unicode pouvant être représentés avec 3 octets dans UTF-8. Vous avez ici un caractère qui nécessite 4 octets: \ xF0 \ x90 \ x8D \ x83 ( U + 10343 LETTRE GOTHIQUE SAUIL ).

Si vous avez MySQL 5.5 ou version ultérieure, vous pouvez changer l’encodage de la colonne de utf8 à utf8mb4 . Cet encodage permet de stocker des caractères qui occupent 4 octets dans UTF-8.

Vous devrez peut-être également définir la propriété du serveur character_set_server sur utf8mb4 dans le fichier de configuration MySQL. Il semble que Connector / J par défaut à 3 octets Unicode sinon :

Par exemple, pour utiliser des jeux de caractères UTF-8 de 4 octets avec Connector / J, configurez le serveur MySQL avec character_set_server=utf8mb4 et laissez characterEncoding dehors de la chaîne de connexion Connector / J. Le connecteur / J détectera alors automatiquement le paramètre UTF-8.

Les chaînes contenant \xF0 sont simplement des caractères codés sous la forme de plusieurs octets utilisant UTF-8.

Bien que votre classement soit défini sur utf8_general_ci, je suppose que le codage des caractères de la firebase database, de la table ou de la colonne même peut être différent. Ce sont des parameters indépendants . Essayer:

 ALTER TABLE database.table MODIFY COLUMN col VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; 

Remplacez le type de données actuel par VARCHAR (255)

Vous avez le même problème, pour enregistrer les données avec utf8mb4 doit vous assurer:

  1. character_set_client, character_set_connection, character_set_results sont utf8mb4 : character_set_client et character_set_connection indiquent le jeu de caractères dans lequel les instructions sont envoyées par le client, character_set_results indique le jeu de caractères dans lequel le serveur renvoie les résultats de la requête au client.
    Voir charset-connection .

  2. l’encodage de la table et de la colonne est utf8mb4

Pour JDBC, il existe deux solutions:

Solution 1 (besoin de redémarrer MySQL):

  1. modifiez my.cnf comme suit et redémarrez MySQL:

     [mysql] default-character-set=utf8mb4 [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci 

Cela peut assurer que la firebase database et character_set_client, character_set_connection, character_set_results sont utf8mb4 par défaut.

  1. redémarrer MySQL

  2. changer l’encodage de la table et de la colonne en utf8mb4

  3. ARRÊTEZ de spécifier characterEncoding=UTF-8 et characterSetResults=UTF-8 dans le connecteur jdbc, car cela remplacera character_set_client , character_set_connection , character_set_results par utf8

Solution 2 (pas besoin de redémarrer MySQL):

  1. changer l’encodage de la table et de la colonne en utf8mb4

  2. spécifiant characterEncoding=UTF-8 dans le connecteur jdbc, car le connecteur jdbc ne supporte pas utf8mb4 .

  3. écrivez votre requête SQL comme ceci (il faut append allowMultiQueries=true au connecteur jdbc):

     'SET NAMES utf8mb4;INSERT INTO Mytable ...'; 

Cela garantit que chaque connexion au serveur, character_set_client,character_set_connection,character_set_results est utf8mb4 .
Voir aussi charset-connection .

Je voulais combiner quelques articles pour en faire une réponse complète, car il semble y avoir quelques étapes.

  1. Ci-dessus les conseils de @madtracey

/etc/mysql/my.cnf ou /etc/mysql/mysql.conf.d/mysqld.cnf

 [mysql] default-character-set=utf8mb4 [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] ## character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 

Encore une fois, des conseils au-dessus de toutes les connexions jdbc avaient characterEncoding=UTF-8 et characterSetResults=UTF-8 retirés d’eux

Avec cet ensemble -Dfile.encoding=UTF-8 semble pas faire de différence.

Je ne pouvais toujours pas écrire de texte international dans db en obtenant le même échec que ci-dessus

Maintenant, en utilisant ce comment-convertir-tout-mysql-database-characterset-et-collation-to-utf-8

Mettez à jour toutes vos utf8mb4 données pour utiliser utf8mb4

 ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 

Exécutez cette requête qui vous indique ce qui doit être sonné

 SELECT CONCAT( 'ALTER TABLE ', table_name, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ', 'ALTER TABLE ', table_name, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ') FROM information_schema.TABLES AS T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` AS C WHERE C.collation_name = T.table_collation AND T.table_schema = 'YOURDB' AND (C.CHARACTER_SET_NAME != 'utf8mb4' OR C.COLLATION_NAME not like 'utf8mb4%') 

Copier la sortie de collage dans l’éditeur remplace tout | avec rien publier dans mysql lorsque connecté à corriger db.

C’est tout ce qui devait être fait et tout semble fonctionner pour moi. Pas le – Dfile.encoding=UTF-8 n’est pas activé et il semble fonctionner comme prévu

E2A Vous avez toujours un problème? Je suis certainement en cours de production, il s’avère donc que vous devez vérifier ce qui a été fait ci-dessus, car cela ne fonctionne pas toujours, voici une raison et un correctif dans ce scénario:

 show create table user `password` varchar(255) CHARACTER SET latin1 NOT NULL, `username` varchar(255) CHARACTER SET latin1 NOT NULL, 

Vous pouvez voir que certains sont encore en train d’essayer de mettre à jour manuellement l’enregistrement:

 ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4; ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes 

Alors réduisons le tout:

 mysql> ALTER TABLE user change username username varchar(255) CHARACTER SET utf8mb4 not NULL; ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes mysql> ALTER TABLE user change username username varchar(100) CHARACTER SET utf8mb4 not NULL; Query OK, 5 rows affected (0.01 sec) 

En bref, j’ai dû réduire la taille de ce champ pour que la mise à jour fonctionne.

Maintenant, quand je cours:

 mysql> ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4; Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 

Tout fonctionne

Dans mon cas, j’ai tout essayé, rien n’a fonctionné. Je suis sûr que ma firebase database ressemble à celle ci-dessous.

 mysql Ver 14.14 Dissortingb 5.7.17, for Linux (x86_64) using EditLine wrapper Connection id: 12 Current database: xxx Current user: yo@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.7.17-0ubuntu0.16.04.1 (Ubuntu) Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/run/mysqld/mysqld.sock Uptime: 42 min 49 sec Threads: 1 Questions: 372 Slow queries: 0 Opens: 166 Flush tables: 1 Open tables: 30 Queries per second avg: 0.144 

donc, je regarde le jeu de colonnes dans chaque table

 show create table company; 

Il s’avère que le jeu de colonnes est en latin. C’est pourquoi, je ne peux pas insérer de chinois dans la firebase database.

  ALTER TABLE company CONVERT TO CHARACTER SET utf8; 

Cela pourrait vous aider. 🙂

fais juste

 ALTER TABLE `some_table` CHARACTER SET = utf8 , COLLATE = utf8_general_ci ; ALTER TABLE `some_table` CHANGE COLUMN `description_with_latin_or_something` `description` TEXT CHARACTER SET 'utf8' NOT NULL ; 

J’ai eu ce problème avec mon application PLAY Java. Ceci est ma trace de stack pour cette exception:

 javax.persistence.PersistenceException: Error[Incorrect ssortingng value: '\xE0\xA6\xAC\xE0\xA6\xBE...' for column 'product_name' at row 1] at io.ebean.config.dbplatform.SqlCodeTranslator.translate(SqlCodeTranslator.java:52) at io.ebean.config.dbplatform.DatabasePlatform.translate(DatabasePlatform.java:192) at io.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:83) at io.ebeaninternal.server.persist.dml.DmlBeanPersister.insert(DmlBeanPersister.java:49) at io.ebeaninternal.server.core.PersistRequestBean.executeInsert(PersistRequestBean.java:1136) at io.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:723) at io.ebeaninternal.server.core.PersistRequestBean.executeNoBatch(PersistRequestBean.java:778) at io.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:769) at io.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:456) at io.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:406) at io.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:393) at io.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1602) at io.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1594) at io.ebean.Model.save(Model.java:190) at models.Product.create(Product.java:147) at controllers.PushData.xlsupload(PushData.java:67) at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$40(Routes.scala:690) at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:134) at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:133) at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$8$$anon$2$$anon$1.invocation(HandlerInvoker.scala:108) at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:88) at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:31) at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:138) at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:655) at scala.util.Success.$anonfun$map$1(Try.scala:251) at scala.util.Success.map(Try.scala:209) at scala.concurrent.Future.$anonfun$map$1(Future.scala:289) at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29) at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29) at scala.concurrent.impl.CallbackRunnable.run$$$capture(Promise.scala:60) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala) at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:56) at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70) at play.core.j.HttpExecutionContext.execute(HttpExecutionContext.scala:48) at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68) at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete(Promise.scala:368) at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete$(Promise.scala:367) at scala.concurrent.impl.Promise$KeptPromise$Successful.onComplete(Promise.scala:375) at scala.concurrent.impl.Promise.transform(Promise.scala:29) at scala.concurrent.impl.Promise.transform$(Promise.scala:27) at scala.concurrent.impl.Promise$KeptPromise$Successful.transform(Promise.scala:375) at scala.concurrent.Future.map(Future.scala:289) at scala.concurrent.Future.map$(Future.scala:289) at scala.concurrent.impl.Promise$KeptPromise$Successful.map(Promise.scala:375) at scala.concurrent.Future$.apply(Future.scala:655) at play.core.j.JavaAction.apply(JavaAction.scala:138) at play.api.mvc.Action.$anonfun$apply$2(Action.scala:96) at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:304) at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37) at scala.concurrent.impl.CallbackRunnable.run$$$capture(Promise.scala:60) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala) at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55) at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91) at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12) at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81) at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91) at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:43) at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) Caused by: java.sql.SQLException: Incorrect ssortingng value: '\xE0\xA6\xAC\xE0\xA6\xBE...' for column 'product_name' at row 1 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) at io.ebeaninternal.server.type.DataBind.executeUpdate(DataBind.java:82) at io.ebeaninternal.server.persist.dml.InsertHandler.execute(InsertHandler.java:122) at io.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:73) ... 59 more 

J’essayais de sauvegarder un enregistrement en utilisant io.Ebean. Je l’ai corrigé en créant ma firebase database avec la collation utf8mb4 et en appliquant l’évolution de la lecture pour recréer toutes les tables afin que toutes les tables soient recréées avec la collation utf-8.

 CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 

C’est principalement dû à certains caractères Unicode. Dans mon cas, c’était le symbole monétaire de la Roupie.

Pour résoudre ce problème rapidement, j’ai dû identifier le personnage à l’origine de cette erreur. Je copie le texte entier collé dans un éditeur de texte comme vi et remplace le caractère troublant par un texte.

J’ai eu le même problème dans mon projet de rails:

 Incorrect ssortingng value: '\xF0\xA9\xB8\xBDs ...' for column 'subject' at row1 

Solution 1: avant d’enregistrer dans db, convertissez la chaîne en base64 par Base64.encode64(subject) et après avoir Base64.decode64(subject) partir de la firebase database, utilisez Base64.decode64(subject)

Solution 2:

Étape 1: Modifier le jeu de caractères (et le classement) de la colonne sujet par

 ALTER TABLE t1 MODIFY subject VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 

Étape 2: Utilisation de database.yml

 encoding :utf8mb4 

ma solution est de changer le type de colonne de varchar (255) en blob

Je veux seulement appliquer le changement uniquement pour un champ, vous pouvez essayer de sérialiser le champ

 class MyModel < ActiveRecord::Base serialize :content attr_accessible :content, :title end 

pour résoudre cette erreur, procédez comme suit:

  1. phpMyAdmin
  2. ta table
  3. “Onglet Structure”
  4. changez le classement de votre champ de latin1_swedish_ci (ou autre chose) en utf8_general_ci