Giá trị chuỗi không chính xác có phải là gì khi cố gắng chèn UTF-8 vào MySQL thông qua JDBC?


228

Đây là cách kết nối của tôi được đặt:
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);

Và tôi đang gặp lỗi sau khi gõ để thêm một hàng vào bảng:
Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...' for column 'content' at row 1

Tôi đang chèn hàng ngàn bản ghi và tôi luôn gặp lỗi này khi văn bản chứa \ xF0 (nghĩa là giá trị chuỗi không chính xác luôn bắt đầu bằng \ xF0).

Đối chiếu của cột là utf8_general_ci.

Điều gì có thể là vấn đề?


Đó sẽ là LATIN NHỎ LETTER N VỚI TILDE (ñ).
andreszs

Đối với những người khác gặp phải vấn đề này, bạn có thể thử: Trên cơ sở dữ liệu: ALTER DATABASE cơ sở dữ liệu_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - Nó sẽ giải quyết các điểm số từ bây giờ trên các bảng được tạo ra. KHÔNG cho các bảng EXIST. Đối với họ, bạn cần phải thực hiện: ALTER TABLE table_name CHUYỂN ĐỔI ĐỂ THIẾT LẬP TÙY CHỌN utf8mb4 THU THẬP utf8mb4_unicode_ci; Nguồn - digitalocean.com/community/questions/ từ
lingar

Câu trả lời:


321

MySQL utf8chỉ cho phép các ký tự Unicode có thể được biểu thị bằng 3 byte trong UTF-8. Tại đây, bạn có một ký tự cần 4 byte: \ xF0 \ x90 \ x8D \ x83 ( U + 10343 GOTHIC LETTER SAUIL ).

Nếu bạn có MySQL 5.5 trở lên, bạn có thể thay đổi mã hóa cột từ utf8thành utf8mb4. Mã hóa này cho phép lưu trữ các ký tự chiếm 4 byte trong UTF-8.

Bạn cũng có thể phải thiết lập thuộc tính máy chủ character_set_serverđể utf8mb4trong file cấu hình MySQL. Có vẻ như Trình kết nối / J mặc định là Unicode 3 byte theo cách khác :

Ví dụ: để sử dụng các bộ ký tự UTF-8 4 byte với Trình kết nối / J, hãy định cấu hình máy chủ MySQL với character_set_server=utf8mb4và thoát characterEncodingkhỏi chuỗi kết nối Trình kết nối / J. Trình kết nối / J sau đó sẽ tự động phát hiện cài đặt UTF-8.


151
Thật là một lựa chọn kỳ quặc để có utf8 thực sự có nghĩa là "tập hợp con của UTF8 có thể được biểu thị bằng 3 byte".
Eric J.

4
character_encoding_serverkhông phải là tên biến cấu hình MySQL hợp lệ. Tôi đã cố gắng đặt character_set_serverthành utf8mb4thay vào đó, ngoài các cột riêng lẻ, nhưng nó không thay đổi gì cả.
Romain Paulus

20
# Đối với mỗi cơ sở dữ liệu: ALTER DATABASE cơ sở dữ liệu_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; # Đối với mỗi bảng: ALTER TABLE table_name CHUYỂN ĐỔI ĐỂ TÙY CHỈNH utf8mb4 THU THẬP utf8mb4_unicode_ci; # Đối với mỗi cột: ALTER TABLE table_name THAY ĐỔI cột_name cột_name VARCHAR (191) CHARACTER SET utf8mb4 THU THẬP utf8mb4_unicode_ci;
iKing

14
Điều kỳ lạ là UTF-8 không phải là UTF-8 cho đến khi được cập nhật thành UTF-8
Klors

3
Vì vậy, bạn đang đề xuất rằng UTF-8 với 3 (ba) byte không thể lưu trữ LATIN SMALL LETTER N VỚI TILDE (ñ) và chúng ta cần 4 (bốn) byte để đánh vần "España" một cách chính xác? Có thật không? Nó có thể vô tư hơn thế này? Chúng ta có thể lưu trữ gì ngoài AZ và 0-9 với 3 byte sau đó ..
andreszs

95

Các chuỗi chứa các ký tự\xF0 đơn giản được mã hóa thành nhiều byte bằng UTF-8.

Mặc dù đối chiếu của bạn được đặt thành utf8_general_ci, tôi nghi ngờ rằng mã hóa ký tự của cơ sở dữ liệu, bảng hoặc cột thậm chí có thể khác nhau. Họ là các thiết lập độc lập . Thử:

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

Thay thế bất cứ loại dữ liệu thực tế nào của bạn là dành cho VARCHAR (255)


4
Thực tế đã thử điều đó, đã không làm việc. Kiểu dữ liệu của cột là LONGTEXT btw, nếu điều này quan trọng.
Lior

1
Ứng dụng của bạn là trong Java tôi lấy nó? Hãy thử gọi Java với file-encodingtham số chỉ định UTF-8, ví dụ java -Dfile.encoding=UTF-8hoặc thêm một công tắc thích hợp trong tệp cấu hình Tomcat (v.v.) của bạn.
Eric J.

1
Tôi đề nghị bạn nhấn mạnh vào "mã hóa ký tự của cơ sở dữ liệu, bảng hoặc cột thậm chí có thể khác nhau" . Đó là điều quan trọng nhất.
Gellie Ann

Bạn cũng sẽ phải thay đổi bảng với CHARACTER SET utf8 COLLATE utf8_general_ci sau đó thay đổi cột CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
Shobhit Sharma

68

Có cùng một vấn đề, để lưu dữ liệu với utf8mb4nhu cầu đảm bảo:

  1. character_set_client, character_set_connection, character_set_resultsutf8mb4: character_set_clientcharacter_set_connectioncho biết bộ ký tự trong đó các câu lệnh được gửi bởi máy khách, character_set_resultscho biết bộ ký tự trong đó máy chủ trả về kết quả truy vấn cho máy khách.
    Xem kết nối bộ ký tự .

  2. bảng mã và cột là utf8mb4

Đối với JDBC, có hai giải pháp:

Giải pháp 1 (cần khởi động lại MySQL):

  1. sửa đổi my.cnfnhư sau và khởi động lại MySQL:

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

điều này có thể đảm bảo cơ sở dữ liệu và character_set_client, character_set_connection, character_set_resultsutf8mb4theo mặc định.

  1. khởi động lại MySQL

  2. thay đổi bảng mã hóa và cột thành utf8mb4

  3. DỪNG quy định cụ thể characterEncoding=UTF-8characterSetResults=UTF-8trong các kết nối jdbc, gây ra điều này sẽ ghi đè character_set_client, character_set_connection, character_set_resultsđểutf8

Giải pháp hai (không cần khởi động lại MySQL):

  1. thay đổi bảng mã hóa và cột thành utf8mb4

  2. Chỉ định characterEncoding=UTF-8trong trình kết nối jdbc, vì trình kết nối jdbc không hỗ trợ utf8mb4.

  3. viết số liệu thống kê sql của bạn như thế này (cần thêm allowMultiQueries=truevào trình kết nối jdbc):

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

điều này sẽ đảm bảo mỗi kết nối đến máy chủ, character_set_client,character_set_connection,character_set_resultsutf8mb4.
Cũng xem kết nối bộ ký tự .


3
Điểm 3 là điểm chốt cho tôi kết hợp với việc thay đổi mã hóa db, bảng và trường: 'SET Nnam utf8mb4; INSERT INTO Mytable ...';
kbbucks

Điểm 3 cũng đã lừa tôi, bảng mã của tôi đã được đặt thành utf8mb4.
Sir_Faenor

Bảng mã chỉ là một mặc định. Nó là đủ để thay đổi mã hóa cột thành utf8mb4.
Rick James

Cách tiếp cận thứ hai nên được sử dụng có chọn lọc, tức là không bao giờ được áp dụng cho SELECTcác truy vấn, vì set names utf8mb4; select ... from ...sẽ không bao giờ tạo ra ResultSetvà thay vào đó dẫn đến một ResultSet is from UPDATE. No Data.lỗi.
Bass

giải pháp 2, chỉ cần mệnh. 1 đã giúp tôi khi tôi đang cố gắng chèn văn bản Cyrillic thông qua hình thức liên lạc của tôi.
Vadim Anisimov

15

Tôi muốn kết hợp một vài bài viết để đưa ra câu trả lời đầy đủ về điều này vì nó dường như là một vài bước.

  1. Lời khuyên trên của @madtracey

/etc/mysql/my.cnf hoặc là /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

Một lần nữa từ lời khuyên trên tất cả các kết nối jdbc đã có characterEncoding=UTF-8characterSetResults=UTF-8xóa khỏi chúng

Với bộ này -Dfile.encoding=UTF-8xuất hiện để không có sự khác biệt.

Tôi vẫn không thể viết văn bản quốc tế vào db bị lỗi như trên

Bây giờ bằng cách sử dụng cách chuyển đổi-an-toàn bộ-mysql-cơ sở dữ liệu-ký tự-và-đối chiếu-thành-utf-8 này

Cập nhật tất cả db của bạn để sử dụng utf8mb4

ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Chạy truy vấn này cung cấp cho bạn những gì cần được rung

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

Sao chép đầu ra dán trong trình chỉnh sửa thay thế tất cả | không có gì đăng lại vào mysql khi được kết nối với db chính xác.

Đó là tất cả những gì phải làm và tất cả dường như làm việc cho tôi. Không phải - Dfile.encoding=UTF-8không được bật và có vẻ như hoạt động như mong đợi

E2A Vẫn có vấn đề? Tôi chắc chắn đang trong quá trình sản xuất nên hóa ra bạn cần phải kiểm tra những gì đã được thực hiện ở trên, vì đôi khi nó không hoạt động, đây là lý do và cách khắc phục trong kịch bản này:

show create table user

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

Bạn có thể thấy một số người vẫn đang cố gắng cập nhật bản ghi theo cách thủ công:

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

Vì vậy, hãy thu hẹp nó xuống:

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)

Nói tóm lại, tôi phải giảm kích thước của trường đó để cập nhật hoạt động.

Bây giờ khi tôi chạy:

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

Tất cả đều hoạt động


Câu hỏi: lệnh ALTER TABLE cuối cùng sẽ chuyển đổi nội dung của tất cả các trường VARCHAR thành chuỗi được mã hóa UTF8 chính hãng, hợp lệ? Tôi hỏi vì tôi gặp vấn đề khi chuyển đổi các trường LATIN1 của mình sang UTF8, cụ thể là khi tìm thấy ký tự, chuyển đổi trực tiếp không thành công do giá trị chuỗi không chính xác (lỗi 1366).
andreszs

nếu bạn có ý nghĩa ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;đủ kỳ lạ khi tôi chạy nó lần cuối cùng thì tất cả các trường không còn có một bộ ký tự được xác định. vì vậy mật khẩu từ trên trở thành passwordvarchar (255) KHÔNG NULL, (không có gì về mã hóa). Điều này có nghĩa là lệnh cuối cùng đơn giản là phải thực hiện tra cứu mysql định nghĩa bảng thực tế là gì và bởi vì bây giờ bảng theo mặc định, các trường này không còn cần nó nữa - tôi cho rằng chúng vẫn tồn tại với bộ ký tự đơn giản vì trong quá trình cập nhật toàn bộ bảng nó không thể cập nhật nó và do đó nó bị bỏ lại ở trạng thái đó
VH

7

Trong trường hợp của tôi, tôi đã thử mọi thứ ở trên, không có gì hiệu quả. Tôi khá chắc chắn, cơ sở dữ liệu của tôi trông như dưới đây.

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

Vì vậy, tôi tìm bảng mã trong mỗi bảng

show create table company;

Hóa ra bộ ký tự cột là tiếng Latin. Đó là lý do tại sao, tôi không thể chèn tiếng Trung vào cơ sở dữ liệu.

 ALTER TABLE company CONVERT TO CHARACTER SET utf8;

Điều đó có thể giúp bạn. :)


7

Tôi đã có cùng một vấn đề trong dự án đường ray của tôi:

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

Giải pháp 1: trước khi lưu vào db chuyển đổi chuỗi thành base64 bằng cách Base64.encode64(subject) và sau khi tìm nạp từ db sử dụngBase64.decode64(subject)

Giải pháp 2:

Bước 1: Thay đổi bộ ký tự (và đối chiếu) cho cột chủ đề bằng

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

Bước 2: Trong cơ sở dữ liệu.yml sử dụng

encoding :utf8mb4

4

cứ làm đi

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 ;

Điều gì xảy ra nếu tôi có một loạt các bảng tôi muốn thay đổi trong cơ sở dữ liệu? và nếu tất cả đều có công cụ lưu trữ khác nhau (innodb, v.v.) thì sao?
Yannis Dran

4

Giả sử bạn đang sử dụng phpmyadmin để giải quyết lỗi này, hãy làm theo các bước sau:

  1. phpMyAdmin
  2. bảng của bạn
  3. "Tab cấu trúc"
  4. thay đổi Collation của lĩnh vực của bạn từ latin1_swedish_ci(hoặc bất kể nó là gì) thànhutf8_general_ci

5
Không hợp lệ, bạn cho rằng anh ta sử dụng phpMyAdmin.
ShaH

không hoạt động ...... và đối chiếu được thay đổi trong 'hoạt động' và không theo cấu trúc
Olorunfemi Ajibulu

@OlorunfemiAjibulu có, bạn cũng có thể thay đổi nó trong "cấu trúc". Đối với một số người ở đây, nó đã hoạt động
Teo Mihaila

@TeoMihaila Có lẽ, đó là phiên bản.
Olorunfemi Ajibulu

3

Nó chủ yếu gây ra do một số ký tự unicode. Trong trường hợp của tôi, đó là biểu tượng tiền tệ Rupee.

Để nhanh chóng khắc phục điều này, tôi đã phải phát hiện ra nhân vật gây ra lỗi này. Tôi sao chép toàn bộ văn bản trong một trình soạn thảo văn bản như vi và thay thế ký tự rắc rối bằng một văn bản.


3
OP đã đề cập rằng có một ngàn hồ sơ được chèn vào ....
Gellie Ann

3

Tôi gặp vấn đề này với ứng dụng Java PLAY của tôi. Đây là dấu vết ngăn xếp của tôi cho ngoại lệ đó:

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

Tôi đã cố lưu bản ghi bằng io.Ebean. Tôi đã sửa nó bằng cách tạo lại cơ sở dữ liệu của mình với đối chiếu utf8mb4 và áp dụng tiến hóa phát để tạo lại tất cả các bảng để tất cả các bảng sẽ được tạo lại với đối chiếu utf-8.

CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

2

Tôi chỉ muốn áp dụng thay đổi cho một trường, bạn có thể thử tuần tự hóa trường

class MyModel < ActiveRecord::Base
  serialize :content

  attr_accessible :content, :title
end

2

Nếu bạn đang tạo một bảng MySQL mới, bạn có thể chỉ định bộ ký tự của tất cả các cột khi tạo và điều đó đã khắc phục sự cố cho tôi.

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

Bạn có thể đọc thêm chi tiết: https://dev.mysql.com/doc/refman/8.0/en/charset-column.html


2

đây không phải là giải pháp đề xuất .. Nhưng đáng để chia sẻ. Vì dự án của tôi đang nâng cấp DBMS từ Mysql cũ lên mới nhất (8). Nhưng tôi không thể thay đổi cấu trúc bảng, chỉ có cấu hình DBMS (mysql). Giải pháp cho máy chủ mysql.

kiểm tra trên Windows mysql 8.0.15 trên tìm kiếm cấu hình mysql cho

chế độ sql = "....."

không chú ý nó Hoặc trong trường hợp của tôi chỉ cần gõ / thêm

sql-mode = "NO_ENGINE_SUBSTITNING"

Tại sao không đề xuất giải pháp. bởi vì nếu bạn sử dụng latin1 (trường hợp của tôi) .. thì việc chèn dữ liệu thành công nhưng không phải là nội dung (mysql không phản hồi với lỗi !!). ví dụ bạn nhập thông tin như thế này

bla \ x12

nó tiết kiệm

bla [] (hộp)

được rồi .. đối với vấn đề của tôi .. Tôi có thể thay đổi trường thành UTF8 .. Nhưng có một vấn đề nhỏ .. xem câu trả lời ở trên về giải pháp khác không thành công vì từ này không được chèn vì chứa hơn 2 byte (cmiiw) .. điều này giải pháp làm cho dữ liệu chèn của bạn trở thành hộp. Hợp lý là sử dụng blob .. và bạn có thể bỏ qua câu trả lời của tôi.

Một thử nghiệm khác liên quan đến điều này là .. sử dụng utf8_encode trên mã của bạn trước khi lưu. Tôi sử dụng trên latin1 và nó đã thành công (Tôi không sử dụng chế độ sql )! giống như câu trả lời ở trên bằng cách sử dụng base64_encode .

Đề nghị của tôi để phân tích yêu cầu bảng của bạn và cố gắng thay đổi từ định dạng khác sang UTF8


Trong cài đặt của tôi (Dự án Django), tôi đã đổi thành sql-mode = "NO_ENGINE_SUBSTITNING". Nó đang hoạt động.
Taciano Morais Silva

1

giải pháp của tôi là thay đổi kiểu cột từ varchar (255) sang blob


1

Bạn cần đặt utf8mb4 trong meta html và máy chủ của bạn cũng thay đổi tabel và đặt đối chiếu thành utf8mb4


1

Gợi ý: Trên AWS RDS, bạn cần một Nhóm tham số mới cho MySQL DB của bạn với các thông số (thay vì chỉnh sửa một 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

Lưu ý: character_set_system vẫn là "utf8"

Các lệnh SQL này KHÔNG LÀM VIỆC HÀNG NGÀY - chỉ trong một phiên:

set character_set_server = utf8mb4;
set collation_server = utf8mb4_unicode_ci;

0

Tôi cũng đã phải bỏ và tạo lại tất cả các thủ tục được lưu trữ của cơ sở dữ liệu (và các hàm cũng vậy) để chúng thực thi trong bộ ký tự mới của utf8mb4.

Chạy:

SHOW PROCEDURE STATUS;

Để xem các thủ tục nào chưa được cập nhật lên các giá trị character_set_client, collation_connection và Database Collation mới của máy chủ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.