"Valeur de chaîne incorrecte" lorsque vous essayez d'insérer UTF-8 dans MySQL via JDBC?

228

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?

Lior
la source
Ce serait la LETTRE MINUSCULE LATINE N TILDE (ñ).
andreszs
Pour d'autres personnes rencontrant ce problème, vous pouvez essayer: Sur la base de données: ALTER DATABASE nom_base_données CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - Il résoudra les tables créées à partir de maintenant. PAS pour les tables EXIST. Pour eux, vous devez faire: ALTER TABLE nom_table CONVERTIR EN CARACTÈRE SET utf8mb4 COLLATE utf8mb4_unicode_ci; Source - digitalocean.com/community/questions/…
lingar

Réponses:

321

MySQL utf8n'autorise que les caractères Unicode qui peuvent être représentés avec 3 octets en UTF-8. Ici, vous avez un caractère qui a besoin de 4 octets: \ xF0 \ x90 \ x8D \ x83 ( U + 10343 GOTHIC LETTER SAUIL ).

Si vous avez MySQL 5.5 ou une version ultérieure, vous pouvez changer l'encodage des colonnes de utf8à utf8mb4. Ce codage permet le stockage de caractères qui occupent 4 octets en UTF-8.

Vous pouvez également définir la propriété du serveur character_set_serverpour utf8mb4dans le fichier de configuration de MySQL. Il semble que le connecteur / J par défaut soit Unicode 3 octets sinon :

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

Joni
la source
151
Quel choix étrange d'avoir utf8 signifie vraiment "le sous-ensemble de UTF8 qui peut être représenté en 3 octets".
Eric J.
4
character_encoding_servern'est pas un nom de variable de configuration MySQL valide. J'ai essayé de définir character_set_serverà la utf8mb4place, en plus des colonnes individuelles, mais cela n'a rien changé.
Romain Paulus du
20
# Pour chaque base de données: ALTER DATABASE nom_base_de_données CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; # Pour chaque table: ALTER TABLE nom_table CONVERTIR EN CARACTERE SET utf8mb4 COLLATE utf8mb4_unicode_ci; # Pour chaque colonne: ALTER TABLE nom_table CHANGE nom_colonne nom_colonne VARCHAR (191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
iKing
14
Bizarre que UTF-8 ne soit pas UTF-8 jusqu'à ce qu'il soit mis à jour pour être UTF-8
Klors
3
Vous suggérez donc que UTF-8 avec 3 (trois) octets ne peut pas stocker la LETTRE MINUSCULE LATINE N AVEC TILDE (ñ), et nous avons besoin de 4 (quatre) octets pour épeler correctement "España"? Vraiment? Cela pourrait-il être plus inefficace que cela? Que pouvons-nous stocker en plus de AZ et 0-9 avec 3 octets alors ..
andreszs
95

Les chaînes qui contiennent \xF0sont simplement des caractères codés sur plusieurs octets à l' aide de UTF-8.

Bien que votre classement soit défini sur 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. Ce sont des paramètres indépendants . Essayer:

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

Remplacez VARCHAR (255) par votre type de données réel

Eric J.
la source
4
En fait, j'ai essayé ça, ça n'a pas marché. Le type de données de la colonne est LONGTEXT btw, si cela est important.
Lior
1
Votre application est en Java, je la prends? Essayez d'invoquer Java avec le file-encodingparamètre spécifiant UTF-8, par exemple java -Dfile.encoding=UTF-8ou ajoutez un commutateur approprié dans votre fichier de configuration Tomcat (etc.).
Eric J.
1
Je vous suggère de mettre l'accent sur "l'encodage des caractères de la base de données, la table ou même la colonne peut être différente" . C’est la chose la plus importante.
Gellie Ann
Vous devrez également modifier la table avec CHARACTER SET utf8 COLLATE utf8_general_ci puis après avoir changé la colonne CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
Shobhit Sharma
68

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

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

  2. le codage de table et de colonne est utf8mb4

Pour JDBC, il existe deux solutions:

Solution 1 (besoin de redémarrer MySQL):

  1. modifiez my.cnfcomme suit et redémarrez MySQL:

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

cela peut garantir que la base de données et character_set_client, character_set_connection, character_set_resultssont utf8mb4par défaut.

  1. redémarrer MySQL

  2. changer le codage de table et de colonne en utf8mb4

  3. ARRÊT spécification characterEncoding=UTF-8et characterSetResults=UTF-8dans le connecteur jdbc, faire ceci surpassera character_set_client, character_set_connection, character_set_resultsàutf8

Deuxième solution (pas besoin de redémarrer MySQL):

  1. changer le codage de table et de colonne en utf8mb4

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

  3. écrivez votre déclaration sql comme ceci (besoin d'ajouter allowMultiQueries=trueau connecteur jdbc):

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

cela garantira que chaque connexion au serveur l' character_set_client,character_set_connection,character_set_resultsest utf8mb4.
Voir aussi charset-connection .

folie
la source
3
Le point 3 a été le pilier pour moi en conjonction avec le changement des encodages db, table et champ: 'SET NAMES utf8mb4; INSERT INTO Mytable ...';
kbbucks
Le point 3 a également fait l'affaire, mon encodage de table étant déjà défini sur utf8mb4.
Sir_Faenor
L'encodage de la table n'est qu'un défaut. Il suffit de changer le codage de la colonne en utf8mb4.
Rick James
La deuxième approche doit être utilisée de manière sélective, c'est-à-dire qu'elle ne doit jamais être appliquée aux SELECTrequêtes, car set names utf8mb4; select ... from ...elle ne produira jamais un ResultSetet entraînera une ResultSet is from UPDATE. No Data.erreur.
Bass
solution 2, juste par. Je m’ai aidé lorsque j’essayais d’insérer du texte en cyrillique dans mon formulaire de contact.
Vadim Anisimov
15

Je voulais combiner quelques articles pour répondre pleinement à cela, car cela semble être 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 à partir des conseils avant tout, les connexions jdbc avaient characterEncoding=UTF-8etcharacterSetResults=UTF-8 retirés de leur

Avec cet ensemble -Dfile.encoding=UTF-8 semblait ne faire aucune différence.

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

Maintenant, en utilisant ce comment-convertir-un-ensemble-de-caractères-de-base-de-données-mysql-et-collation-en-utf-8

Mettez à jour tous vos db pour les utiliser utf8mb4

ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Exécutez cette requête qui vous donne 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 remplacer tout | sans rien poster dans mysql lorsqu'il est connecté pour corriger la base de données.

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 rencontrez toujours un problème? Je suis certainement en production, il s'avère que vous devez vérifier ce qui a été fait ci-dessus, car cela ne fonctionne parfois pas, voici la raison et la solution 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étrécissons-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

VH
la source
Question: la dernière commande ALTER TABLE convertira le contenu de tous les champs VARCHAR en une chaîne codée UTF8 authentique et valide? Je demande parce que j'ai des problèmes pour convertir mes champs LATIN1 en UTF8, en particulier lorsque le caractère ñ est trouvé, la conversion échoue directement en raison d'une valeur de chaîne incorrecte (erreur 1366).
andreszs
si vous voulez dire ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;étrangement quand j'ai exécuté cela la dernière fois, tous les champs n'avaient plus de jeu de caractères défini. donc le mot de passe ci-dessus est devenu passwordvarchar (255) NOT NULL, (rien sur l'encodage). Cela signifie que la dernière commande doit simplement avoir recherché mysql quelle était la définition réelle de la table et parce que maintenant la table était par défaut, les champs n'en ont plus besoin - je suppose qu'ils sont restés avec le jeu de caractères simplement parce que pendant le vidage des mises à jour de la table entière il ne pouvait pas le mettre à jour et il a donc été laissé dans cet état
VH
7

Dans mon cas, j'ai tout essayé ci-dessus, rien n'a fonctionné. Je suis sûr que 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 recherche 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. :)

crazy_phage
la source
7

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

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

Solution 1: avant d'enregistrer en db, convertissez la chaîne en base64 par Base64.encode64(subject) et après la récupération à partir de l'utilisation de la base de donnéesBase64.decode64(subject)

Solution 2:

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

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

Étape 2: dans le fichier database.yml, utilisez

encoding :utf8mb4
ravi
la source
4

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 ;
shareef
la source
que faire si j'ai un tas de tables que je veux changer dans la base de données? et si tous ont un moteur de stockage différent (innodb, etc.)?
Yannis Dran
4

En supposant que vous utilisez phpmyadmin pour résoudre cette erreur, procédez comme suit:

  1. phpMyAdmin
  2. ta table
  3. "Onglet Structure"
  4. changer le classement de votre champ de latin1_swedish_ci(ou quoi que ce soit) enutf8_general_ci
Teo Mihaila
la source
5
Non valide, vous supposez qu'il utilise phpMyAdmin.
ShaH
ne fonctionne pas ...... et le classement est modifié en "fonctionnement" et non en structure
Olorunfemi Ajibulu
@OlorunfemiAjibulu oui, vous pouvez également le changer dans la "structure". Pour certaines personnes ici, cela a fonctionné
Teo Mihaila
@TeoMihaila C'est peut-être du versioning.
Olorunfemi Ajibulu
3

Cela est principalement dû à certains caractères unicode. Dans mon cas, c'était le symbole de la monnaie Roupie.

Pour résoudre ce problème rapidement, j'ai dû repérer 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.

BTR Naidu
la source
3
Le PO a mentionné qu'il y avait mille enregistrements insérés ....
Gellie Ann
3

J'ai eu ce problème avec mon application Java PLAY. 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é l'évolution du jeu pour recréer toutes les tables afin que toutes les tables soient recréées avec le classement utf-8.

CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Md Ashfak Chowdhury
la source
2

Si vous ne souhaitez appliquer la modification qu'à un seul champ, vous pouvez essayer de sérialiser le champ

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end
Paul Marclay
la source
2

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, et cela 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

amucunguzi
la source
2

ce n'est pas la solution de recommandation .. Mais vaut la peine d'être partagée. Depuis mon projet, mettre à niveau le SGBD de l'ancien Mysql vers le plus récent (8). Mais je ne peux pas changer la structure de la table, seule la configuration du SGBD (mysql). La solution pour le serveur mysql.

test sous Windows mysql 8.0.15 sur mysql config recherche de

sql-mode = "....."

le décommenter. Ou dans mon cas, il suffit de taper / ajouter

sql-mode = "NO_ENGINE_SUBSTITUTION"

pourquoi pas la solution recommandée. car si vous utilisez latin1 (mon cas) .. l'insertion des données réussie mais pas le contenu (mysql ne répond pas avec erreur !!). par exemple, vous tapez des informations comme celle-ci

bla \ x12

ça sauve

bla [] (encadré)

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é car le mot n'est pas inséré car contient plus de 2 octets (cmiiw) .. ce solution faire vos données d'insertion devenir boîte. Le raisonnable est d'utiliser blob .. et vous pouvez sauter ma réponse.

Un autre test lié à cela était .. en utilisant utf8_encode sur votre code avant d'enregistrer. J'utilise sur latin1 et ce fut un succès (je n'utilise pas le mode sql )! même réponse que ci-dessus en utilisant base64_encode .

Ma suggestion pour analyser les exigences de votre table et essayer de passer d'un autre format à UTF8

user2905554
la source
Dans mon settings.py (projet Django), je suis passé à sql-mode = "NO_ENGINE_SUBSTITUTION". Ça marche.
Taciano Morais Silva
1

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

zhuochen shen
la source
1

Vous devez définir utf8mb4 en méta html et également dans votre serveur alter tabel et définir le classement sur utf8mb4

Sona Israyelyan
la source
1

Astuce: sur AWS RDS, vous avez besoin d'un nouveau groupe de paramètres pour votre base de données MySQL avec les paramètres (au lieu de modifier un my.cnf)

  • collation_connection: utf8mb4_unicode_ci
  • collation_database: utf8mb4_unicode_ci
  • collation_server: utf8mb4_unicode_ci
  • character_set_client: utf8mb4
  • character_set_connection: utf8mb4
  • character_set_database: utf8mb4
  • character_set_results: utf8mb4
  • character_set_server: utf8mb4

Remarque: character_set_system reste "utf8"

Ces commandes SQL NE FONCTIONNENT PAS DE MANIÈRE PERMANENTE - uniquement dans une session:

set character_set_server = utf8mb4;
set collation_server = utf8mb4_unicode_ci;
électrobabe
la source
0

J'ai également dû supprimer et recréer toutes les procédures stockées de la base de données (et les fonctions aussi) afin qu'elles s'exécutent dans le nouveau jeu de caractères d'utf8mb4.

Courir:

SHOW PROCEDURE STATUS;

… Pour voir quelles procédures n'ont pas été mises à jour avec les nouvelles valeurs du serveur character_set_client, collation_connection et Database Collation.

Ethan Allen
la source