Voici comment ma connexion est établie:Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);
Et j'obtiens l'erreur suivante lorsque je tente d'ajouter une ligne à une table:Incorrect string 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 (c'est-à-dire que 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?
Le _utf8
_ de MySQL n'autorise que les caractères Unicode pouvant être représentés avec 3 octets en UTF-8. Ici, vous avez un caractère qui nécessite 4 octets:\xF0\x90\x8D\x83 ( + 10343 LETTRE GOTHIC SAUIL ).
Si vous avez MySQL 5.5 ou une version ultérieure, vous pouvez modifier le codage de la colonne de _utf8
_ à utf8mb4
. Ce codage 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 utilise par défaut un format Unicode à 3 octets :
Par exemple, pour utiliser des jeux de caractères UTF-8 sur 4 octets avec Connector/J, configurez le serveur MySQL avec _
character_set_server=utf8mb4
_ et laissezcharacterEncoding
en dehors de la chaîne de connexion Connector/J. Connector/J détecte ensuite automatiquement le paramètre UTF-8.
Les chaînes contenant \xF0
sont simplement caractères codés sur plusieurs octets utilisant UTF-8.
Bien que votre classement soit défini sur utf8_general_ci, je soupçonne que le codage de 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 . Essayer:
ALTER TABLE database.table MODIFY COLUMN col VARCHAR(255)
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
Remplacez votre type de données actuel par VARCHAR (255)
Vous avez le même problème, pour enregistrer les données avec utf8mb4
, vous devez vous assurer que:
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 interroger les résultats auprès du client.
Voir charset-connection .
le codage de table et de colonne est utf8mb4
Pour JDBC, il existe deux solutions:
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 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
changez l'encodage de la table et de la colonne en utf8mb4
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
en utf8
changez l'encodage de la table et de la colonne en utf8mb4
en spécifiant characterEncoding=UTF-8
dans le connecteur jdbc, le connecteur jdbc ne supporte pas utf8mb4
.
écrivez votre déclaration SQL comme ceci (vous devez ajouter allowMultiQueries=true
au connecteur jdbc):
'SET NAMES utf8mb4;INSERT INTO Mytable ...';
cela permettra de s'assurer 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 donner une réponse complète, car il semble y avoir quelques étapes.
/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 par conseil, les connexions jdbc avaient characterEncoding=UTF-8
et characterSetResults=UTF-8
supprimées
Avec cet ensemble, -Dfile.encoding=UTF-8
semblait ne faire aucune différence.
Je ne pouvais toujours pas écrire de texte international dans la base de données obtenant le même échec que ci-dessus
Maintenant, en utilisant ceci comment-convertir-un-ensemble-mysql-base-caractères-et-collation-en-utf-8
Mettez à jour toute votre base de 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 appelé
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 la sortie dans l'éditeur remplace tout | avec rien poster dans mysql lorsqu'il est 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 production, il est donc nécessaire de vérifier ce qui a été fait ci-dessus, car cela arrive parfois. ne fonctionne pas, voici la raison et résoudre 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 toujours en train de tenter de mettre à jour l'enregistrement manuellement:
ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
Alors affinons le:
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é ci-dessus, rien n'a fonctionné. Je suis assez sûr, ma base de données ressemble à celle 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
alors, je regarde le jeu de caractères de la colonne dans chaque table
show create table company;
Il s'avère que le jeu de caractères de la colonne est latin. C'est pourquoi, je ne peux pas insérer de chinois dans la base de données.
ALTER TABLE company CONVERT TO CHARACTER SET utf8;
Cela pourrait vous aider. :)
En supposant que vous utilisez phpmyadmin pour résoudre cette erreur, procédez comme suit:
latin1_swedish_ci
(ou quoi que ce soit) en utf8_general_ci
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. Voici 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$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 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 le classement utf8mb4 et appliqué play evolution pour recréer toutes les tables de manière à ce que toutes les tables soient recréées avec le classement en utf-8.
CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
J'ai eu le même problème dans mon Rails projet:
Incorrect string value: '\xF0\xA9\xB8\xBDs ...' for column 'subject' at row1
Solution 1: avant d'enregistrer dans la base de données, convertissez la chaîne en base64 de Base64.encode64(subject)
et après l'extraction de la base de données, utilisez Base64.decode64(subject)
.
Solution 2:
Étape 1: modifiez 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: Dans database.yml, utilisez
encoding :utf8mb4
C'est principalement dû à certains caractères Unicode. Dans mon cas, c'était le symbole monétaire de la roupie.
Pour résoudre rapidement ce problème, je devais repérer le personnage à l'origine de cette erreur. J'ai copié le texte entier dans un éditeur de texte comme vi et j'ai remplacé le caractère troublant par un texte.
Si vous ne souhaitez appliquer la modification qu'à un seul champ, vous pouvez essayer de le sérialiser.
class MyModel < ActiveRecord::Base
serialize :content
attr_accessible :content, :title
end
Vous devez définir utf8mb4 en méta html et également dans votre serveur, modifiez tabel et définissez le classement sur utf8mb4.
Si vous créez une nouvelle table MySQL, vous pouvez spécifier le jeu de caractères de toutes les colonnes lors de la création, ce qui a résolu le problème pour moi.
CREATE TABLE tablename (
<list-of-columns>
)
CHARSET SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Vous pouvez lire plus de détails: https://dev.mysql.com/doc/refman/8.0/en/charset-column.html
ma solution est de changer le type de colonne de varchar (255) à blob
ce n'est pas la solution de recommandation .. Mais vaut la peine de partager. Depuis mon projet, mettez à niveau le SGBD de Mysql ancien vers le plus récent (8). Mais je ne peux pas changer la structure de la table, seulement la configuration du SGBD (mysql). La solution pour le serveur mysql.
test sur Windows mysql 8.0.15 sur mysql config recherche
sql-mode = "....."
décommentez-le. Ou dans mon cas, tapez/ajoutez
sql-mode = "NO_ENGINE_SUBSTITUTION"
pourquoi pas solution recommandée. parce que si vous utilisez latin1 (mon cas) .. les données ont été insérées avec succès mais pas le contenu (mysql ne répond pas avec une erreur !!). par exemple vous tapez info comme ça
bla\x12
ça sauve
bla [] (boîte)
ok .. pour mon problème .. je peux changer le champ en UTF8 .. Mais il y a un petit problème .. voir la réponse ci-dessus à propos d'une autre solution a échoué parce que le mot n'est pas inséré car contient plus de 2 octets (cmiiw) .. this solution pour que vos données d’insertion deviennent une boîte. Le raisonnable est d'utiliser blob .. et vous pouvez ignorer ma réponse.
Un autre test lié à cela était .. en utilisant tf8_encode sur votre code avant de sauvegarder. J'utilise sur latin1 et c'était un succès (je n'utilise pas sql-mode)! Identique à la réponse ci-dessus en utilisant base64_encode.
Ma suggestion pour analyser votre besoin de table et essayé de passer d'un autre format à UTF8