„Niepoprawna wartość ciągu” podczas próby wstawienia UTF-8 do MySQL przez JDBC?

228

Oto jak ustawia się moje połączenie:
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);

I pojawia się następujący błąd podczas wiązania w celu dodania wiersza do tabeli:
Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...' for column 'content' at row 1

Wstawiam tysiące rekordów i zawsze pojawia się ten błąd, gdy tekst zawiera \ xF0 (tj. Niepoprawna wartość ciągu zawsze zaczyna się od \ xF0).

Zestawienie kolumny to utf8_general_ci.

Co może być problemem?

Lior
źródło
Byłby to LATIN MAŁY LITER N Z TILDE (ñ).
andreszs,
W przypadku innych problemów można spróbować: W bazie danych: ALTER DATABASE nazwa_bazy_danych ZESTAW ZNAKÓW utf8mb4 COLLATE utf8mb4_unicode_ci; - Rozwiąże „utworzone odtąd” tabele. NIE dla tabel EXIST. Dla nich musisz zrobić: ALTER TABLE nazwa_tabeli KONWERSJA NA ZESTAW ZNAKÓW utf8mb4 COLLATE utf8mb4_unicode_ci; Źródło - digitalocean.com/community/questions/...
lingar

Odpowiedzi:

321

MySQL utf8dopuszcza tylko znaki Unicode, które mogą być reprezentowane 3 bajtami w UTF-8. Tutaj masz znak, który potrzebuje 4 bajtów: \ xF0 \ x90 \ x8D \ x83 ( U + 10343 GOTHIC LITTER SAUIL ).

Jeśli masz MySQL 5.5 lub nowszy, możesz zmienić kodowanie kolumn z utf8na utf8mb4. To kodowanie umożliwia przechowywanie znaków zajmujących 4 bajty w UTF-8.

Można również ustawić właściwość serwera character_set_server, aby utf8mb4w pliku konfiguracyjnym MySQL. Wygląda na to, że inaczej Connector / J ma domyślnie 3-bajtowy Unicode :

Na przykład, aby używać 4-bajtowych zestawów znaków UTF-8 z łącznikiem / J, skonfiguruj serwer MySQL za pomocą character_set_server=utf8mb4i pomiń characterEncodingciąg połączenia / łącznika. Złącze / J automatycznie wykryje ustawienie UTF-8.

Joni
źródło
151
Co za dziwny wybór posiadania utf8 naprawdę oznacza „podzbiór UTF8, który może być reprezentowany w 3 bajtach”.
Eric J.
4
character_encoding_servernie jest prawidłową nazwą zmiennej konfiguracyjnej MySQL. Próbowałem zestaw character_set_serverdo utf8mb4zamiast, oprócz poszczególnych kolumn, ale to niczego nie zmienia.
Romain Paulus
20
# Dla każdej bazy danych: ALTER DATABASE nazwa_bazy_danych ZNAK ZESTAW = utf8mb4 COLLATE = utf8mb4_unicode_ci; # Dla każdej tabeli: ALTER TABLE nazwa_tabeli KONWERSJA NA ZESTAW ZNAKÓW utf8mb4 COLLATE utf8mb4_unicode_ci; # Dla każdej kolumny: ALTER TABLE nazwa_tabeli ZMIANA nazwa_kolumny nazwa_kolumny VARCHAR (191) ZNAK ZESTAWU utf8mb4 COLLATE utf8mb4_unicode_ci;
iKing
14
Dziwne, że UTF-8 nie jest UTF-8, dopóki nie zostanie zaktualizowany do UTF-8
Klors
3
Sugerujesz więc, że UTF-8 z 3 (trzema) bajtami nie może przechowywać LATIN MAŁEGO LITERA N Z TILDE (ñ), a my potrzebujemy 4 (czterech) bajtów, aby poprawnie przeliterować „España”? Naprawdę? Czy to może być bardziej przydatne niż to? Co możemy przechowywać poza AZ i 0-9 z 3 bajtami następnie ...
andreszs
94

Zawarte w niej ciągi znaków \xF0to po prostu znaki zakodowane jako wiele bajtów za pomocą UTF-8.

Mimo że sortowanie jest ustawione na utf8_general_ci, podejrzewam, że kodowanie znaków w bazie danych, tabeli lub nawet kolumnie może być inne. Są to niezależne ustawienia . Próbować:

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

Zastąp bez względu na faktyczny typ danych VARCHAR (255)

Eric J.
źródło
4
Właściwie to próbowałem, nie działało. Typ danych kolumny to LONGTEXT btw, jeśli to ma znaczenie.
Lior
1
Twoja aplikacja jest w Javie Rozumiem? Spróbuj wywołać Javę z file-encodingparametrem określającym UTF-8, np. java -Dfile.encoding=UTF-8Lub dodaj odpowiedni przełącznik w pliku konfiguracyjnym Tomcat (itp.).
Eric J.
1
Sugeruję, aby położyć nacisk na „kodowanie znaków w bazie danych, tabeli lub nawet kolumnie może być inne” . To jest najważniejsze.
Gellie Ann,
Trzeba będzie również zmienić tabelę za pomocą CHARACTER SET utf8 COLLATE utf8_general_ci, a następnie po zmianie kolumny CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
Shobhit Sharma
68

Masz ten sam problem, aby zapisać dane, utf8mb4musisz się upewnić:

  1. character_set_client, character_set_connection, character_set_resultsare utf8mb4: character_set_clienti character_set_connectionwskazują zestaw znaków, w którym klient wysyła instrukcje, character_set_resultswskazuje zestaw znaków, w którym serwer zwraca klientowi wyniki zapytania.
    Zobacz charset-connection .

  2. kodowanie tabeli i kolumny to utf8mb4

W przypadku JDBC istnieją dwa rozwiązania:

Rozwiązanie 1 (trzeba ponownie uruchomić MySQL):

  1. zmodyfikuj my.cnfjak poniżej i zrestartuj MySQL:

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

może to zapewnić, że baza danych character_set_client, character_set_connection, character_set_resultsjest utf8mb4domyślnie.

  1. zrestartuj MySQL

  2. zmień kodowanie tabeli i kolumny na utf8mb4

  3. Stop określania characterEncoding=UTF-8i characterSetResults=UTF-8w jdbc złącza powodować zastąpi character_set_client, character_set_connection, character_set_resultsdoutf8

Rozwiązanie drugie (nie trzeba restartować MySQL):

  1. zmień kodowanie tabeli i kolumny na utf8mb4

  2. określając characterEncoding=UTF-8w złączu jdbc, ponieważ złącze jdbc nie obsługuje utf8mb4.

  3. napisz swoją instrukcję SQL w następujący sposób (musisz dodać allowMultiQueries=truedo konektora jdbc):

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

Dzięki temu każde połączenie z serwerem character_set_client,character_set_connection,character_set_resultsbędzie utf8mb4.
Zobacz także charset-connection .

madtracy
źródło
3
Punkt 3 był dla mnie klinicystą w związku ze zmianą kodowania db, table & field: „SET NAMES utf8mb4; INSERT INTO Mytable ...”;
kbbucks
Punkt 3 również mi pomógł, moje kodowanie tabeli jest już ustawione na utf8mb4.
Sir_Faenor
Kodowanie tabeli jest tylko ustawieniem domyślnym. Wystarczy zmienić kodowanie kolumny na utf8mb4.
Rick James
Drugie podejście powinno być stosowane selektywnie, tzn. Nigdy nie powinno być stosowane do SELECTzapytań, ponieważ set names utf8mb4; select ... from ...nigdy nie wygeneruje a, ResultSeta zamiast tego spowoduje ResultSet is from UPDATE. No Data.błąd.
Bass
rozwiązanie 2, tylko par. Pomogłem mi, gdy próbowałem wstawić tekst w cyrylicy przez formularz kontaktowy.
Vadim Anisimov
15

Chciałem połączyć kilka postów, aby uzyskać pełną odpowiedź na to pytanie, ponieważ wydaje się, że to kilka kroków.

  1. Powyżej porady @madtracey

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

Ponownie z porad wynika, że ​​wszystkie połączenia jdbc miały characterEncoding=UTF-8i characterSetResults=UTF-8zostały z nich usunięte

Z tym zestawem -Dfile.encoding=UTF-8wydawało się, że nie ma znaczenia.

Nadal nie mogłem napisać międzynarodowego tekstu do db, otrzymując taką samą awarię jak powyżej

Teraz korzystamy z tego jak przekonwertować-cały-mysql-database-characterset-and-collation-to-utf-8

Zaktualizuj całą bazę danych do użycia utf8mb4

ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Uruchom to zapytanie, które daje ci to, co należy szczebla

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

Kopiuj wyniki wklejania w edytorze zastąp wszystkie | nic nie przesyła z powrotem do mysql po podłączeniu do poprawnej bazy danych.

To wszystko, co trzeba było zrobić i wydaje mi się, że wszystko działa. Nie - Dfile.encoding=UTF-8nie jest włączony i wydaje się działać zgodnie z oczekiwaniami

E2A Nadal masz problem? Z pewnością jestem w produkcji, więc okazuje się, że musisz sprawdzić, co zostało zrobione powyżej, ponieważ czasami to nie działa, oto powód i naprawa w tym scenariuszu:

show create table user

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

Widać, że niektórzy nadal łacińscy próbują ręcznie zaktualizować rekord:

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

Więc zawęźmy to:

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)

Krótko mówiąc musiałem zmniejszyć rozmiar tego pola, aby aktualizacja działała.

Teraz kiedy biegnę:

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

To wszystko działa

VH
źródło
Pytanie: ostatnie polecenie ALTER TABLE przekształci zawartość wszystkich pól VARCHAR w prawidłowy, autentyczny ciąg kodowany w UTF8? Pytam, ponieważ mam problemy z konwersją moich pól LATIN1 na UTF8, szczególnie po znalezieniu znaku ñ, konwersja bezpośrednio kończy się niepowodzeniem z powodu niepoprawnej wartości ciągu (błąd 1366).
andreszs,
jeśli masz na myśli ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;dziwnie, kiedy uruchomiłem to po raz ostatni, wszystkie pola nie miały już zdefiniowanego zestawu znaków. więc hasło z góry stało się passwordvarchar (255) NOT NULL, (nic o kodowaniu). Oznacza to, że ostatnie polecenie po prostu sprawiło, że mysql sprawdziło, jaka była rzeczywista definicja tabeli, a ponieważ teraz tabela była domyślnie tym, pola już jej nie potrzebują - zakładam, że pozostały z zestawem znaków po prostu dlatego, że podczas zrzutu całej aktualizacji tabeli nie mógł go zaktualizować i dlatego został pozostawiony w tym stanie
VH
7

W moim przypadku próbowałem wszystkiego powyżej, nic nie działało. Jestem całkiem pewien, że moja baza danych wygląda jak poniżej.

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

więc sprawdzam zestaw znaków kolumny w każdej tabeli

show create table company;

Okazuje się, że zestaw znaków kolumny jest łaciński. Dlatego nie mogę wstawić chińskiego do bazy danych.

 ALTER TABLE company CONVERT TO CHARACTER SET utf8;

To może ci pomóc. :)

crazy_phage
źródło
7

Miałem ten sam problem w moim projekcie szyn:

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

Rozwiązanie 1: przed zapisaniem do db przekonwertuj ciąg znaków na base64 przez Base64.encode64(subject) i po pobraniu z dbBase64.decode64(subject)

Rozwiązanie 2:

Krok 1: Zmień zestaw znaków (i układanie) dla kolumny tematu o

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

Krok 2: W użyciu database.yml

encoding :utf8mb4
ravi
źródło
4

po prostu zrób

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
źródło
co jeśli mam kilka tabel, które chcę zmienić w bazie danych? a co jeśli wszystkie mają inny silnik pamięci masowej (innodb itp.)?
Yannis Dran
4

Zakładając, że używasz phpmyadmin do rozwiązania tego błędu, wykonaj następujące kroki:

  1. phpMyAdmin
  2. Twój stół
  3. „Karta Struktura”
  4. zmień sortowanie swojego pola z latin1_swedish_ci(lub cokolwiek to jest) nautf8_general_ci
Teo Mihaila
źródło
5
Niepoprawne, podejrzewasz, że używa phpMyAdmina.
ShaH,
nie działa ...... i układanie jest zmieniane w „działaniu”, a nie w strukturze
Olorunfemi Ajibulu
@OlorunfemiAjibulu tak, możesz to również zmienić w „strukturze”. Dla niektórych osób tutaj zadziałało
Teo Mihaila
@TeoMihaila Być może jest to wersja.
Olorunfemi Ajibulu
3

Jest to głównie spowodowane niektórymi znakami Unicode. W moim przypadku był to symbol waluty rupii.

Aby to szybko naprawić, musiałem zauważyć postać powodującą ten błąd. Skopiowałem wkleiłem cały tekst w edytorze tekstu, takim jak vi, i zastąpiłem problematyczny znak tekstowym.

BTR Naidu
źródło
3
OP wspomniał, że wstawiono tysiąc rekordów ...
Gellie Ann,
3

Miałem ten problem z aplikacją PLAY Java. To jest mój ślad stosu dla tego wyjątku:

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

Próbowałem zapisać rekord za pomocą io.Ebean. Naprawiłem to, ponownie tworząc moją bazę danych z sortowaniem utf8mb4, i zastosowałem ewolucję odtwarzania, aby ponownie utworzyć wszystkie tabele, tak aby wszystkie tabele mogły zostać odtworzone z sortowaniem utf-8.

CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Md Ashfak Chowdhury
źródło
2

Jeśli chcesz zastosować zmianę tylko do jednego pola, możesz spróbować serializować to pole

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end
Paul Marclay
źródło
2

Jeśli tworzysz nową tabelę MySQL, możesz określić zestaw znaków dla wszystkich kolumn podczas tworzenia, co rozwiązało problem.

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

Możesz przeczytać więcej szczegółów: https://dev.mysql.com/doc/refman/8.0/en/charset-column.html

amucunguzi
źródło
2

nie jest to rozwiązanie rekomendacyjne. Ale warto się tym podzielić. Ponieważ moim projektem jest aktualizacja DBMS ze starego MySQL do najnowszego (8). Ale nie mogę zmienić struktury tabeli, tylko konfiguracja DBMS (mysql). Rozwiązanie dla serwera mysql.

test w systemie Windows mysql 8.0.15 podczas wyszukiwania konfiguracji mysql

tryb sql = "....."

odkomentuj to. Lub w moim przypadku po prostu wpisz / dodaj

tryb sql = "NO_ENGINE_SUBSTITUTION"

dlaczego nie zalecane rozwiązanie. ponieważ jeśli użyjesz latin1 (mój przypadek) .. dane wstawiane są sukcesywnie, ale nie zawartość (mysql nie odpowiada błędem !!). na przykład wpisujesz takie informacje

bla \ x12

to oszczędza

bla [] (pole)

ok .. dla mojego problemu .. Mogę zmienić pole na UTF8 .. Ale jest mały problem .. patrz wyżej odpowiedź o innym rozwiązaniu nie powiodła się, ponieważ słowo nie zostało wstawione, ponieważ zawiera więcej niż 2 bajty (cmiiw) .. to rozwiązanie sprawi, że wstawione dane staną się skrzynkami. Rozsądne jest użycie obiektu blob ... i możesz pominąć moją odpowiedź.

Kolejnymi związanymi z tym testami były .. użycie utf8_encode w kodzie przed zapisaniem. Używam na latin1 i to był sukces (nie używam trybu sql )! taka sama jak powyższa odpowiedź przy użyciu base64_encode .

Moja sugestia, aby przeanalizować wymagania dotyczące tabeli i próbować zmienić z innego formatu na UTF8

użytkownik2905554
źródło
W moim settings.py (Django Project) zmieniłem tryb na sql = "NO_ENGINE_SUBSTITUTION". To działa.
Taciano Morais Silva
1

moim rozwiązaniem jest zmiana typu kolumny z varchar (255) na blob

zhuochen shen
źródło
1

Musisz ustawić utf8mb4 w meta html, a także na serwerze zmienić tabelę i ustawić sortowanie na utf8mb4

Sona Israyelyan
źródło
1

Wskazówka: W systemie AWS RDS potrzebujesz nowej grupy parametrów dla bazy danych MySQL z parametrami (zamiast edycji pliku my.cnf)

  • collation_connection: utf8mb4_unicode_ci
  • baza danych_kolacji: utf8mb4_unicode_ci
  • collation_server: utf8mb4_unicode_ci
  • zestaw_znaków_klienta: utf8mb4
  • połączenie_zestawem_znaków: utf8mb4
  • zestaw_znaków_bazy_danych: utf8mb4
  • character_set_results: utf8mb4
  • serwer_znaków_znaków: utf8mb4

Uwaga: character_set_system pozostaje „utf8”

Te polecenia SQL NIE DZIAŁAJĄ STAŁO - tylko podczas sesji:

set character_set_server = utf8mb4;
set collation_server = utf8mb4_unicode_ci;
electrobabe
źródło
0

Musiałem także usunąć i ponownie utworzyć wszystkie procedury przechowywane w bazie danych (i funkcje), aby mogły zostać wykonane w ramach nowego zestawu znaków utf8mb4.

Biegać:

SHOW PROCEDURE STATUS;

… Aby zobaczyć, które procedury nie zostały zaktualizowane do nowych wartości server_set_client, collation_connection i Database Collation.

Ethan Allen
źródło