"Falscher Zeichenfolgenwert" beim Versuch, UTF-8 über JDBC in MySQL einzufügen?

228

So wird meine Verbindung hergestellt:
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);

Beim Versuch, einer Zeile eine Zeile hinzuzufügen, wird folgende Fehlermeldung angezeigt:
Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...' for column 'content' at row 1

Ich füge Tausende von Datensätzen ein und erhalte immer diesen Fehler, wenn der Text \ xF0 enthält (dh der falsche Zeichenfolgenwert beginnt immer mit \ xF0).

Die Sortierung der Spalte lautet utf8_general_ci.

Was könnte das Problem sein?

Lior
quelle
Das wäre LATEINISCHER KLEINBUCHSTABE N MIT TILD (ñ).
Andreszs
Bei anderen, die auf dieses Problem stoßen, können Sie Folgendes versuchen: In der Datenbank: ALTER DATABASE Datenbankname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - Es wird die von nun an erstellten Tabellen lösen. NICHT für EXIST-Tabellen. Für sie müssen Sie Folgendes tun: ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; Quelle - digitalocean.com/community/questions/…
Lingar

Antworten:

321

MySQL utf8erlaubt nur die Unicode-Zeichen, die in UTF-8 mit 3 Bytes dargestellt werden können. Hier haben Sie ein Zeichen, das 4 Bytes benötigt: \ xF0 \ x90 \ x8D \ x83 ( U + 10343 GOTHIC LETTER SAUIL ).

Wenn Sie über MySQL 5.5 oder höher verfügen, können Sie die Spaltencodierung von utf8auf ändern utf8mb4. Diese Codierung ermöglicht die Speicherung von Zeichen, die 4 Bytes in UTF-8 belegen.

Sie können auch die Server - Eigenschaft müssen , character_set_serverum utf8mb4in der MySQL - Konfigurationsdatei. Ansonsten scheint Connector / J standardmäßig 3-Byte-Unicode zu verwenden :

Wenn Sie beispielsweise 4-Byte-UTF-8-Zeichensätze mit Connector / J verwenden möchten, konfigurieren Sie den MySQL-Server mit character_set_server=utf8mb4und lassen Sie characterEncodingdie Connector / J-Verbindungszeichenfolge weg . Connector / J erkennt dann automatisch die UTF-8-Einstellung.

Joni
quelle
150
Was für eine seltsame Wahl, utf8 zu haben, bedeutet wirklich "die Teilmenge von UTF8, die in 3 Bytes dargestellt werden kann".
Eric J.
4
character_encoding_serverist kein gültiger MySQL-Konfigurationsvariablenname. Ich habe versucht , Satz character_set_serverzu utf8mb4statt, zusätzlich zu den einzelnen Spalten, aber es hat nichts ändern.
Romain Paulus
20
# Für jede Datenbank: ALTER DATABASE Datenbankname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; # Für jede Tabelle: ALTER TABLE tabellenname CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # Für jede Spalte: ALTER TABLE Tabellenname CHANGE Spaltenname Spaltenname VARCHAR (191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
iKing
14
Seltsam, dass UTF-8 nicht UTF-8 ist, bis es auf UTF-8 aktualisiert wird
Klors
3
Sie schlagen also vor, dass UTF-8 mit 3 (drei) Bytes LATIN SMALL LETTER N WITH TILDE (ñ) nicht speichern kann und wir 4 (vier) Bytes benötigen, um "España" richtig zu buchstabieren? "Ja wirklich?" Könnte es unzulänglicher sein? Was können wir außer AZ und 0-9 mit 3 Bytes dann speichern ..
andreszs
94

Die darin enthaltenen Zeichenfolgen \xF0sind einfach Zeichen, die mit UTF-8 als mehrere Bytes codiert wurden .

Obwohl Ihre Sortierung auf utf8_general_ci festgelegt ist, vermute ich, dass die Zeichenkodierung der Datenbank, Tabelle oder sogar Spalte unterschiedlich sein kann. Sie sind unabhängige Einstellungen . Versuchen:

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

Ersetzen Sie VARCHAR (255) durch einen beliebigen Datentyp.

Eric J.
quelle
4
Eigentlich versucht, hat nicht funktioniert. Der Datentyp der Spalte ist übrigens LONGTEXT, wenn dies wichtig ist.
Lior
1
Deine App ist in Java, nehme ich an? Versuchen Sie, Java mit dem file-encodingParameter UTF-8 aufzurufen , z. B. java -Dfile.encoding=UTF-8oder fügen Sie einen geeigneten Schalter in Ihre Tomcat-Konfigurationsdatei (usw.) ein.
Eric J.
1
Ich schlage vor, Sie legen einen Schwerpunkt auf "Die Zeichencodierung der Datenbank, Tabelle oder sogar Spalte kann unterschiedlich sein" . Das ist das Wichtigste.
Gellie Ann
Sie müssen die Tabelle auch mit CHARACTER SET utf8 COLLATE utf8_general_ci ändern. Nach dem Ändern der Spalte CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
Shobhit Sharma
68

Habe das gleiche Problem, um die Daten zu speichern, utf8mb4muss sichergestellt werden:

  1. character_set_client, character_set_connection, character_set_resultsare utf8mb4: character_set_clientund character_set_connectiongeben den Zeichensatz an, in dem Anweisungen vom Client gesendet werden. character_set_resultsGibt den Zeichensatz an, in dem der Server Abfrageergebnisse an den Client zurückgibt.
    Siehe Zeichensatzverbindung .

  2. Die Tabellen- und Spaltencodierung lautet utf8mb4

Für JDBC gibt es zwei Lösungen:

Lösung 1 (MySQL muss neu gestartet werden):

  1. Ändern Sie my.cnfwie folgt und starten Sie MySQL neu:

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

Dies kann sicher die Datenbank machen und character_set_client, character_set_connection, character_set_resultssind utf8mb4standardmäßig aktiviert .

  1. Starten Sie MySQL neu

  2. Ändern Sie die Tabellen- und Spaltencodierung in utf8mb4

  3. STOP - Angabe characterEncoding=UTF-8und characterSetResults=UTF-8im jdbc Anschluss, verursachen diese außer Kraft gesetzt werden character_set_client, character_set_connection, character_set_resultszuutf8

Lösung zwei (MySQL muss nicht neu gestartet werden):

  1. Ändern Sie die Tabellen- und Spaltencodierung in utf8mb4

  2. Angabe characterEncoding=UTF-8in dem jdbc Anschluss, Ursache der jdbc Anschluss nicht suport tut utf8mb4.

  3. Schreiben Sie Ihre SQL-Anweisung wie folgt (müssen Sie allowMultiQueries=truezum JDBC-Connector hinzufügen ):

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

Dadurch wird sichergestellt, dass jede Verbindung zum Server character_set_client,character_set_connection,character_set_resultsbesteht utf8mb4.
Siehe auch Zeichensatzverbindung .

Madtracy
quelle
3
Punkt 3 war für mich der Clou in Verbindung mit der Änderung der Datenbank-, Tabellen- und Feldcodierungen: 'SET NAMES utf8mb4; INSERT INTO Mytable ...';
Kbbucks
Punkt 3 hat auch für mich den Trick gemacht, meine Tabellencodierung ist bereits auf utf8mb4 eingestellt.
Sir_Faenor
Die Tabellencodierung ist nur eine Standardeinstellung. Es reicht aus, die Spaltencodierung in utf8mb4 zu ändern.
Rick James
Der zweite Ansatz sollte selektiv verwendet werden, dh niemals auf SELECTAbfragen angewendet werden, da er set names utf8mb4; select ... from ...niemals einen erzeugt ResultSetund stattdessen zu einem ResultSet is from UPDATE. No Data.Fehler führt.
Bass
Lösung 2, nur Par. Ich habe mir geholfen, als ich versucht habe, kyrillischen Text über mein Kontaktformular einzufügen.
Vadim Anisimov
15

Ich wollte ein paar Beiträge kombinieren, um eine vollständige Antwort darauf zu erhalten, da es sich anscheinend um ein paar Schritte handelt.

  1. Oben Rat von @madtracey

/etc/mysql/my.cnf oder /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

Wieder von Ratschlägen vor allem hatten characterEncoding=UTF-8und haben jdbc Verbindungen characterSetResults=UTF-8von ihnen entfernt

Mit diesem Set -Dfile.encoding=UTF-8schien es keinen Unterschied zu machen.

Ich konnte immer noch keinen internationalen Text in db schreiben und bekam den gleichen Fehler wie oben

Verwenden Sie nun diese Anleitung zum Konvertieren eines vollständigen MySQL-Datenbank-Zeichensatzes und einer Kollatierung in utf-8

Aktualisieren Sie Ihre gesamte Datenbank, um sie zu verwenden utf8mb4

ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Führen Sie diese Abfrage aus, die angibt, was angerufen werden muss

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%')

Kopieren Einfügen Ausgabe im Editor Ersetzen Sie alle | mit nichts Post zurück in MySQL, wenn mit korrekter Datenbank verbunden.

Das war alles was getan werden musste und alles scheint für mich zu funktionieren. Nicht das - Dfile.encoding=UTF-8ist nicht aktiviert und es scheint wie erwartet zu funktionieren

E2A Haben Sie immer noch ein Problem? Ich bin auf jeden Fall in der Produktion, es stellt sich also heraus, dass Sie überprüfen müssen, was oben getan wurde, da es manchmal nicht funktioniert. Hier ist Grund und Fehler in diesem Szenario:

show create table user

  `password` varchar(255) CHARACTER SET latin1 NOT NULL,
  `username` varchar(255) CHARACTER SET latin1 NOT NULL,

Sie können sehen, dass einige noch in Latein versuchen, den Datensatz manuell zu aktualisieren:

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

Lassen Sie es uns eingrenzen:

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)

Kurz gesagt, ich musste die Größe dieses Felds reduzieren, damit das Update funktioniert.

Wenn ich jetzt renne:

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

Es funktioniert alles

VH
quelle
Frage: Der letzte Befehl ALTER TABLE konvertiert den Inhalt aller VARCHAR-Felder in eine gültige, echte UTF8-codierte Zeichenfolge. Ich frage, weil ich Probleme beim Konvertieren meiner LATIN1-Felder in UTF8 habe, insbesondere wenn das Zeichen ñ gefunden wird, schlägt die Konvertierung direkt aufgrund eines falschen Zeichenfolgenwerts fehl (Fehler 1366).
andreszs
Wenn Sie das ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;seltsamerweise meinen , als ich dies das letzte Mal ausführte, war für alle Felder kein Zeichensatz mehr definiert. Das Passwort von oben wurde also zu passwordvarchar (255) NOT NULL (nichts über Codierung). Dies bedeutet, dass der letzte Befehl einfach dazu geführt haben muss, dass MySQL nach der tatsächlichen Tabellendefinition gesucht hat, und da die Tabelle nun standardmäßig so war, dass die Felder sie nicht mehr benötigen - ich nehme an, sie blieben beim Zeichensatz, nur weil während des Dumps der gesamten Tabellenaktualisierungen es konnte es nicht aktualisieren und daher wurde es in diesem Zustand belassen
VH
7

In meinem Fall habe ich alles oben versucht, nichts hat funktioniert. Ich bin mir ziemlich sicher, meine Datenbank sieht wie folgt aus.

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

Also schaue ich in jeder Tabelle nach dem Spaltenzeichensatz

show create table company;

Es stellt sich heraus, dass der Spaltenzeichensatz lateinisch ist. Deshalb kann ich kein Chinesisch in die Datenbank einfügen.

 ALTER TABLE company CONVERT TO CHARACTER SET utf8;

Das könnte dir helfen. :) :)

crazy_phage
quelle
7

Ich hatte das gleiche Problem in meinem Rails-Projekt:

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

Lösung 1: Konvertieren Sie vor dem Speichern in db den String durch Base64.encode64(subject) und nach dem Abrufen von db use in base64 Base64.decode64(subject)

Lösung 2:

Schritt 1: Ändern Sie den Zeichensatz (und die Sortierung) für die Betreffspalte um

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

Schritt 2: In database.yml verwenden

encoding :utf8mb4
Ravi
quelle
4

mach einfach

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
quelle
Was ist, wenn ich eine Reihe von Tabellen in der Datenbank ändern möchte? und was ist, wenn alle unterschiedliche Speicher-Engines haben (innodb usw.)?
Yannis Dran
4

Angenommen, Sie verwenden phpmyadmin , um diesen Fehler zu beheben , gehen Sie folgendermaßen vor:

  1. phpMyAdmin
  2. dein Tisch
  3. Registerkarte "Struktur"
  4. Ändern Sie die Sortierung Ihres Feldes von latin1_swedish_ci(oder was auch immer es ist) inutf8_general_ci
Teo Mihaila
quelle
5
Nicht gültig, Sie nehmen an, er verwendet phpMyAdmin.
ShaH
funktioniert nicht ...... und die Sortierung wird in 'Operation' und nicht in Struktur geändert
Olorunfemi Ajibulu
@OlorunfemiAjibulu ja, du kannst es auch in "Struktur" ändern. Für einige Leute hier hat es funktioniert
Teo Mihaila
@TeoMihaila Vielleicht ist es Versionierung.
Olorunfemi Ajibulu
3

Es ist hauptsächlich auf einige Unicode-Zeichen zurückzuführen. In meinem Fall war es das Rupienwährungssymbol.

Um dies schnell zu beheben, musste ich den Charakter erkennen, der diesen Fehler verursachte. Ich habe den gesamten Text in einen Texteditor wie vi eingefügt und das störende Zeichen durch einen Text ersetzt.

BTR Naidu
quelle
3
Das OP erwähnte, dass tausend Datensätze eingefügt werden ....
Gellie Ann
3

Ich hatte dieses Problem mit meiner PLAY Java-Anwendung. Dies ist meine Stapelverfolgung für diese Ausnahme:

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

Ich habe versucht, einen Datensatz mit io.Ebean zu speichern. Ich habe das Problem behoben, indem ich meine Datenbank mit der Kollatierung utf8mb4 neu erstellt und die Play Evolution angewendet habe, um alle Tabellen neu zu erstellen, sodass alle Tabellen mit der Kollatierung utf-8 neu erstellt werden sollten.

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

Wenn Sie die Änderung nur für ein Feld anwenden möchten, können Sie versuchen, das Feld zu serialisieren

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end
Paul Marclay
quelle
2

Wenn Sie eine neue MySQL-Tabelle erstellen, können Sie den Zeichensatz aller Spalten bei der Erstellung angeben. Dadurch wurde das Problem für mich behoben.

CREATE TABLE tablename (
<list-of-columns>
)
CHARSET SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Weitere Informationen finden Sie unter: https://dev.mysql.com/doc/refman/8.0/en/charset-column.html

Amucunguzi
quelle
2

Dies ist nicht die Empfehlungslösung. Aber es lohnt sich zu teilen. Seit meinem Projekt wird das DBMS von altem MySQL auf neuestes (8) aktualisiert. Aber ich kann die Tabellenstruktur nicht ändern, nur die DBMS-Konfiguration (MySQL). Die Lösung für MySQL Server.

Test auf Windows - mysql 8.0.15 auf mysql config - Suche

sql-mode = "....."

kommentiere es aus. Oder in meinem Fall einfach eingeben / hinzufügen

sql-mode = "NO_ENGINE_SUBSTITUTION"

warum nicht empfohlene Lösung. denn wenn Sie latin1 verwenden (mein Fall) .. die Daten erfolgreich einfügen, aber nicht den Inhalt (MySQL nicht mit Fehler antworten !!). Zum Beispiel geben Sie solche Informationen ein

bla \ x12

es sparen

bla [] (Box)

okay .. für mein Problem .. ich kann das Feld in UTF8 ändern .. aber es gibt ein kleines Problem .. siehe oben Antwort über andere Lösung ist fehlgeschlagen, weil das Wort nicht eingefügt wird, weil mehr als 2 Bytes (cmiiw) enthalten .. dies Lösung machen Ihre Daten einfügen Box. Der vernünftige ist, Blob zu verwenden .. und Sie können meine Antwort überspringen.

Ein weiterer diesbezüglicher Test war .. Verwenden von utf8_encode für Ihren Code vor dem Speichern. Ich benutze auf latin1 und es war ein Erfolg (ich benutze nicht den SQL-Modus )! Gleiche Antwort wie oben mit base64_encode .

Mein Vorschlag, Ihre Tabellenanforderungen zu analysieren und zu versuchen, von einem anderen Format zu UTF8 zu wechseln

user2905554
quelle
In meiner settings.py (Django-Projekt) habe ich in sql-mode = "NO_ENGINE_SUBSTITUTION" geändert. Es funktioniert.
Taciano Morais Silva
1

Meine Lösung besteht darin, den Spaltentyp von varchar (255) in blob zu ändern

zhuochen shen
quelle
1

Sie müssen utf8mb4 in Meta-HTML und auch auf Ihrem Server festlegen, die Tabelle ändern und die Sortierung auf utf8mb4 setzen

Sona Israyelyan
quelle
1

Hinweis: Auf AWS RDS benötigen Sie eine neue Parametergruppe für Ihre MySQL-Datenbank mit den Parametern (anstatt eine my.cnf zu bearbeiten).

  • collation_connection: utf8mb4_unicode_ci
  • collation_database: utf8mb4_unicode_ci
  • collation_server: utf8mb4_unicode_ci
  • zeichen_set_client: utf8mb4
  • zeichen_set_verbindung: utf8mb4
  • character_set_database: utf8mb4
  • character_set_results: utf8mb4
  • character_set_server: utf8mb4

Hinweis: character_set_system bleibt "utf8"

Diese SQL-Befehle funktionieren NICHT DAUERHAFT - nur in einer Sitzung:

set character_set_server = utf8mb4;
set collation_server = utf8mb4_unicode_ci;
Elektrobabe
quelle
0

Ich musste auch alle gespeicherten Prozeduren (und Funktionen) der Datenbank löschen und neu erstellen, damit sie innerhalb des neuen Zeichensatzes von utf8mb4 ausgeführt werden.

Lauf:

SHOW PROCEDURE STATUS;

… Um zu sehen, welche Prozeduren nicht auf die neuen Werte Character_set_client, Collation_connection und Database Collation des Servers aktualisiert wurden.

Ethan Allen
quelle