[mysql] JDBC를 통해 MySQL에 UTF-8을 삽입하려고 할 때 “잘못된 문자열 값”?

이것은 내 연결이 설정된 방법입니다.
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);

그리고 테이블에 행을 추가하려고 할 때 다음 오류가 발생합니다.
Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...' for column 'content' at row 1

수천 개의 레코드를 삽입하고 있는데 텍스트에 \ xF0이 포함 된 경우 항상이 오류가 발생합니다 (즉, 잘못된 문자열 값은 항상 \ xF0으로 시작 함).

열 데이터 정렬은 utf8_general_ci입니다.

무엇이 문제 일 수 있습니까?



답변

MySQL utf8은 UTF-8에서 3 바이트로 표현할 수있는 유니 코드 문자 만 허용합니다. 여기에는 4 바이트가 필요한 문자가 있습니다 : \ xF0 \ x90 \ x8D \ x83 ( U + 10343 GOLTIC LETTER SAUIL ).

MySQL 5.5 이상이있는 경우 열 인코딩을에서 utf8로 변경할 수 있습니다 utf8mb4. 이 인코딩을 사용하면 4 바이트를 차지하는 문자를 UTF-8로 저장할 수 있습니다.

MySQL 구성 파일에서 서버 속성 character_set_server을 로 설정해야 할 수도 있습니다 utf8mb4. 그렇지 않으면 Connector / J의 기본값은 3 바이트 유니 코드로 보입니다 .

예를 들어, 커넥터 / J와 4 바이트 UTF-8 문자 세트를 사용하여 MySQL 서버를 구성 character_set_server=utf8mb4하고 떠나 characterEncoding커넥터 / J 연결 문자열 부족합니다. 그러면 Connector / J가 UTF-8 설정을 자동 감지합니다.


답변

포함 된 문자열은 UTF-8을 사용하여 \xF0단순히 여러 바이트로 인코딩 된 문자 입니다.

데이터 정렬이 utf8_general_ci로 설정되어 있지만 데이터베이스, 테이블 또는 열의 문자 인코딩이 다를 수 있습니다. 이들은 독립적 인 설정 입니다. 시험:

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

VARCHAR (255)에 대한 실제 데이터 유형을 대체하십시오.


답변

동일한 문제가 발생하여 데이터를 저장하려면 다음 utf8mb4을 확인해야합니다.

  1. character_set_client, character_set_connection, character_set_resultsare utf8mb4: character_set_clientcharacter_set_connection클라이언트가 명령문을 보내는 character_set_results문자 세트를 나타내며, 서버가 조회 결과를 클라이언트에 리턴하는 문자 세트를 나타냅니다. charset-connection을
    참조하십시오 .

  2. 테이블 및 열 인코딩은 utf8mb4

JDBC의 경우 두 가지 솔루션이 있습니다.

솔루션 1 (MySQL을 다시 시작해야 함) :

  1. my.cnf다음과 같이 수정 하고 MySQL을 다시 시작하십시오.

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

이 있는지 데이터베이스를 만들 수 character_set_client, character_set_connection, character_set_results있습니다 utf8mb4기본적으로.

  1. MySQL을 다시 시작

  2. 테이블 및 열 인코딩을 다음으로 변경하십시오. utf8mb4

  3. STOP을 지정 characterEncoding=UTF-8하고 characterSetResults=UTF-8JDBC를 커넥터에,이 우선합니다 원인 character_set_client, character_set_connection, character_set_resultsutf8

해결 방법 2 (MySQL을 다시 시작할 필요가 없음) :

  1. 테이블 및 열 인코딩을 다음으로 변경하십시오. utf8mb4

  2. characterEncoding=UTF-8jdbc 커넥터에서 지정 하면 jdbc 커넥터가 지원하지 않기 때문 utf8mb4입니다.

  3. 다음과 같이 SQL 통계를 작성하십시오 ( allowMultiQueries=truejdbc 커넥터 에 추가해야 함 ).

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

이렇게하면 서버에 대한 각 연결 character_set_client,character_set_connection,character_set_resultsutf8mb4입니다. charset-connection
도 참조하십시오 .


답변

몇 가지 단계로 보이 므로이 게시물에 대한 전체 답변을 얻기 위해 몇 개의 게시물을 결합하고 싶었습니다.

  1. 위의 조언은 @madtracey

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

다시 조언 모든 JDBC 연결이 있었다 위 characterEncoding=UTF-8하고 characterSetResults=UTF-8그들로부터 제거

이 세트 -Dfile.encoding=UTF-8로 아무런 차이가없는 것처럼 보입니다.

위와 동일한 실패로 인해 여전히 국제 텍스트를 DB에 쓸 수 없습니다.

이제이 방법을 사용하여 전체 MySQL 데이터베이스 데이터베이스 문자 집합과 데이터 정렬 UTF-8로 변환

사용할 모든 DB를 업데이트하십시오. utf8mb4

ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

렁이 필요한 것을 제공하는이 쿼리를 실행하십시오.

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

편집기에서 붙여 넣기 출력 복사 모두 바꾸기 | 올바른 DB에 연결되면 mysql에 다시 게시되는 것이 없습니다.

그것이 완료되어야 할 전부이며 모두 나를 위해 일하는 것 같습니다. – Dfile.encoding=UTF-8가 활성화되어 있지 않으며 예상대로 작동하는 것 같습니다.

E2A 여전히 문제가 있습니까?
나는 확실히 생산 중이므로 때로는 작동하지 않기 때문에 위의 작업을 확인해야한다는 것이 밝혀졌습니다.이 시나리오의 이유는 다음과 같습니다.

show create table user

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

일부는 여전히 라틴어가 수동으로 레코드를 업데이트하려고 시도하는 것을 볼 수 있습니다.

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

좁 히자 :

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)

즉, 업데이트가 작동하려면 해당 필드의 크기를 줄여야했습니다.

이제 내가 달릴 때 :

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

모두 작동합니다


답변

제 경우에는 위의 모든 것을 시도했지만 아무것도 작동하지 않았습니다. 내 데이터베이스는 다음과 같이 보입니다.

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

그래서 나는 모든 테이블에서 열 문자 세트를 찾습니다.

show create table company;

열 문자 집합이 라틴어 인 것으로 나타났습니다. 그래서 데이터베이스에 중국어를 삽입 할 수 없습니다.

 ALTER TABLE company CONVERT TO CHARACTER SET utf8;

도움이 될 것입니다. 🙂


답변

레일 프로젝트에서 같은 문제가 발생했습니다.

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

해결 방법 1 : db로 Base64.encode64(subject)
가져 오기 전후 에 db 변환 문자열을 base64로 저장하기 전에 Base64.decode64(subject)

해결책 2 :

1 단계 : 주제 열의 문자 집합 (및 데이터 정렬)을 다음과 같이 변경합니다.

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

2 단계 : database.yml에서

encoding :utf8mb4


답변

그냥 해

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 ;