"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?
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 laissercharacterEncoding
hors de la chaîne de connexion Connecteur/J. Connecteur / J va ensuite autodétecter le réglage UTF-8.
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)
a eu le même problème, pour enregistrer les données avec utf8mb4
doit être sûr:
-
character_set_client, character_set_connection, character_set_results
sontutf8mb4
:character_set_client
etcharacter_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 . -
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):
-
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.
-
redémarrer MySQL
-
changer le tableau et la colonne codant pour
utf8mb4
-
arrêtez de spécifier
characterEncoding=UTF-8
etcharacterSetResults=UTF-8
dans le connecteur jdbc, car cela va surchargercharacter_set_client
,character_set_connection
,character_set_results
àutf8
Solution de deux (n'avez pas besoin de redémarrer MySQL):
-
changer le tableau et le codage de la colonne en
utf8mb4
-
spécifiant
characterEncoding=UTF-8
dans le connecteur jdbc,car le connecteur jdbc ne supporte pasutf8mb4
. -
é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 .
j'ai voulu combiner les deux posts pour faire une réponse complète, car il semble que quelques étapes.
- 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
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. :)
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 ;
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;
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.
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
ma solution est de changer le type de colonne de type varchar(255) blob
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
pour résoudre cette erreur, suivez ces étapes:
- phpMyAdmin
- your_table
- "151960920 la" Structure de l'onglet"
- changez la Collation de votre champ de
latin1_swedish_ci
(ou quoi que ce soit) àutf8_general_ci