"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 quand tyring ajouter une ligne à une table:

Incorrect string value: 'xF0x90x8Dx83xF0x90...' for column 'content' at row 1

j'insère des milliers d'enregistrements, et j'obtiens toujours cette erreur lorsque le texte contient xF0 (c'est-à-dire que la valeur de la chaîne incorrecte commence toujours par xF0).

la compilation de la colonne est utf8_general_ci.

Quel est le problème?

150
demandé sur Mathias Bynens 2012-06-09 03:46:11

12 réponses

MySQL utf8 permet de l'Unicode des caractères qui peut être représenté avec 3 octets en UTF-8. Ici vous avez un caractère qui nécessite 4 octets: \xF0\x90\x8D\x83 ( U+10343 lettre gothique SAUIL ).

si vous avez MySQL 5.5 ou plus tard, vous pouvez changer le codage de colonne de utf8 à utf8mb4 . Ce codage permet de stocker des caractères qui occupent 4 octets en UTF-8.

Vous pouvez également définir la propriété du serveur character_set_server à utf8mb4 dans le fichier de configuration MySQL. Il semble que Connecteur / J par défaut à 3 octets Unicode autrement :

par exemple, pour utiliser des jeux de caractères UTF-8 de 4 octets avec connecteur/J, configurer le serveur MySQL avec character_set_server=utf8mb4 , et laisser characterEncoding hors de la chaîne de connexion Connecteur/J. Connecteur / J va ensuite autodétecter le réglage UTF-8.

229
répondu Joni 2017-07-06 18:47:26

les chaînes qui contiennent \xF0 sont simplement des caractères codés en octets multiples en utilisant UTF-8.

bien que votre collation soit définie à utf8_general_ci, je soupçonne que le codage des caractères de la base de données, de la table ou même de la colonne peut être différent. Ils sont paramètres indépendants . Essayez:

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

remplacer quel que soit votre type de données réel est pour VARCHAR(255)

59
répondu Eric J. 2017-05-23 12:10:43

a eu le même problème, pour enregistrer les données avec utf8mb4 doit être sûr:

  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 déclarations 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-connexion .

  2. le codage de la table et de la colonne est utf8mb4

pour JDBC, il y a deux solutions:

la Solution 1 (besoin de redémarrer MySQL):

  1. modifier my.cnf comme suit et redémarrer MySQL:

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

cela permet de s'assurer que la base de données et character_set_client, character_set_connection, character_set_results sont utf8mb4 par défaut.

  1. redémarrer MySQL

  2. changer le tableau et la colonne codant pour utf8mb4

  3. arrêtez de spécifier characterEncoding=UTF-8 et characterSetResults=UTF-8 dans le connecteur jdbc, car cela va surcharger character_set_client , character_set_connection , character_set_results à utf8

Solution de deux (n'avez pas besoin de redémarrer MySQL):

  1. changer le tableau et le codage 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 statut sql comme ceci (besoin d'ajouter allowMultiQueries=true au connecteur jdbc):

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

chaque connexion au serveur character_set_client,character_set_connection,character_set_results sont utf8mb4 .

Voir aussi charset-connexion .

31
répondu madtracy 2017-11-20 09:56:23

j'ai voulu combiner les deux posts pour faire une réponse complète, car il semble que quelques étapes.

  1. ci-dessus Conseil 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 à partir des conseils avant tout JDBC connexions avait characterEncoding=UTF-8 et characterSetResults=UTF-8 retiré d'eux

avec cet ensemble -Dfile.encoding=UTF-8 ne semble faire aucune différence.

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

Maintenant, à l'aide de cette comment-convertir-un-ensemble-mysql-base de données-characterset-et-classement-à-utf-8

mettre à jour tous vos db pour utiliser utf8mb4

ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

exécuter cette requête qui vous donne ce qui doit être exécuté

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 coller sortie dans l'éditeur remplacer tout / avec rien post de nouveau dans mysql une fois connecté à la bonne 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 Encore d'avoir un problème ? Je suis certainement dans la production donc il s'avère que vous devez vérifier ce qui a été fait par ci-dessus, car il ne fonctionne parfois pas, voici raison et correction 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 certains sont encore latin tentative de mise à jour manuelle de l'enregistrement:

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

Donc, nous allons préciser:

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 afin d'obtenir la mise à jour fonctionne.

Maintenant, quand je lance:

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

6
répondu Vahid 2017-05-23 11:54:59

dans mon cas, j'ai tout essayé ci-dessus, rien n'a fonctionné. Je suis assez sûr, ma base de données ressemble à ci-dessous.

mysql  Ver 14.14 Distrib 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 la colonne charset est Latine. C'est pourquoi, je ne peux pas insérer le chinois dans la base de données.

 ALTER TABLE company CONVERT TO CHARACTER SET utf8;

Qui pourrait vous aider. :)

2
répondu crazy_phage 2017-03-31 03:01:09

just do

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 ;
1
répondu shareef 2017-05-23 15:17:43

j'ai eu ce problème avec mon application PLAY Java. C'est ma trace de pile pour cette exception:

javax.persistence.PersistenceException: Error[Incorrect string 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.$anonfun$applyOrElse(Routes.scala:690)
  at play.core.routing.HandlerInvokerFactory$$anon.resultCall(HandlerInvoker.scala:134)
  at play.core.routing.HandlerInvokerFactory$$anon.resultCall(HandlerInvoker.scala:133)
  at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$$anon$$anon.invocation(HandlerInvoker.scala:108)
  at play.core.j.JavaAction$$anon.call(JavaAction.scala:88)
  at play.http.DefaultActionCreator.call(DefaultActionCreator.java:31)
  at play.core.j.JavaAction.$anonfun$apply(JavaAction.scala:138)
  at scala.concurrent.Future$.$anonfun$apply(Future.scala:655)
  at scala.util.Success.$anonfun$map(Try.scala:251)
  at scala.util.Success.map(Try.scala:209)
  at scala.concurrent.Future.$anonfun$map(Future.scala:289)
  at scala.concurrent.impl.Promise.liftedTree1(Promise.scala:29)
  at scala.concurrent.impl.Promise.$anonfun$transform(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.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(Action.scala:96)
  at scala.concurrent.Future.$anonfun$flatMap(Future.scala:304)
  at scala.concurrent.impl.Promise.$anonfun$transformWith(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(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 string 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 recréant ma base de données avec la collation utf8mb4, et j'ai appliqué l'évolution de jeu pour recréer toutes les tables de sorte que toutes les tables devraient être recréées avec la collation utf-8.

CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
1
répondu Md Ashfak Chowdhury 2018-07-26 10:03:08

est principalement causé par des caractères unicode. Dans mon cas, c'était le symbole de la Roupie.

pour corriger rapidement cette erreur, j'ai dû repérer le caractère à l'origine de cette erreur. J'ai copié collé tout le texte dans un éditeur de texte comme vi et remplacé le caractère troublant par un texte.

0
répondu BTR Naidu 2016-04-12 07:09:34

j'ai eu le même problème dans mon projet rails:

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

Solution 1: avant d'économiser en db convertissez la chaîne en base64 par Base64.encode64(subject) et après récupération de db utiliser Base64.decode64(subject)

Solution 2:

Étape 1: Changer le jeu de caractères (et la compilation) pour la colonne Objet par

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

Étape 2: dans la base de données.yml utiliser

encoding :utf8mb4
0
répondu ravi 2017-05-24 21:06:12

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

0
répondu zhuochen shen 2017-07-07 06:44:17

I vous voulez seulement appliquer la modification pour un seul champ, vous pouvez essayer de sérialiser le champ

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end
0
répondu Paul Marclay 2017-10-03 21:58:18

pour résoudre cette erreur, suivez ces étapes:

  1. phpMyAdmin
  2. your_table
  3. "151960920 la" Structure de l'onglet"
  4. changez la Collation de votre champ de latin1_swedish_ci (ou quoi que ce soit) à utf8_general_ci
0
répondu Teo Mihaila 2018-03-02 12:04:17