java.sql.SQLException : 잘못된 문자열 값 : '\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F…'


107

다음 문자열 값이 있습니다. "walmart obama 👽💔"

MySQL과 Java를 사용하고 있습니다.

다음 예외가 발생합니다.`java.sql.SQLException : 잘못된 문자열 값 : '\ xF0 \ x9F \ x91 \ xBD \ xF0 \ x9F ...'

삽입하려는 변수는 다음과 같습니다.

var1 varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL`

"walmart obama 👽💔"를 삽입하려는 Java 코드가 준비된 상태입니다. 그래서 나는 setString()방법을 사용하고 있습니다.

문제는 👽💔 값의 인코딩 인 것 같습니다. 이 문제를 어떻게 해결할 수 있습니까? 이전에는 Derby SQL을 사용했고 👽💔 값은 2 sqaures로 끝났습니다 (나는 이것이 널 문자의 표현이라고 생각합니다)

모든 도움에 감사드립니다!



데이터베이스를 만들 때 다음과 같은 문자 집합과 데이터 정렬을 제공 할 수 있습니다.CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Max Peng

답변:


145

당신이 가진 것은 EXTRATERRESTRIAL ALIEN (U+1F47D)하고 BROKEN HEART (U+1F494)있는 기본 다국어 평면에 있지 않습니다. 그들은 자바에서 하나의 문자로 표현 될 수도 없습니다 "👽💔".length() == 4. 확실히 null 문자가 아니며 지원하는 글꼴을 사용하지 않으면 사각형이 표시됩니다.

MySQL utf8은 기본 다국어 평면 만 지원하며 utf8mb4대신 다음 을 사용해야 합니다 .

보충 문자의 경우 utf8은 문자를 전혀 저장할 수 없지만 utf8mb4는이를 저장하는 데 4 바이트가 필요합니다. utf8은 문자를 전혀 저장할 수 없기 때문에 utf8 열에 보충 문자가 없으며 이전 버전의 MySQL에서 utf8 데이터를 업그레이드 할 때 문자 변환이나 데이터 손실에 대해 걱정할 필요가 없습니다.

따라서 이러한 문자를 지원하려면 MySQL이 5.5 이상이어야하며 utf8mb4모든 곳 에서 사용해야 합니다. 연결 인코딩은이어야 utf8mb4하고 문자 세트는이어야 utf8mb4하며 조합은이어야 utf8mb4합니다. Java의 경우 여전히 "utf-8"이지만 MySQL에는 구별이 필요합니다.

어떤 드라이버를 사용하고 있는지 모르겠지만 드라이버에 구애받지 않는 연결 문자 집합을 설정하는 방법은 쿼리를 보내는 것입니다.

SET NAMES 'utf8mb4'

연결 직후.

Connector / J에 대한 내용도 참조하십시오 .

14.14 : Connector / J에서 4 바이트 UTF8, utf8mb4를 어떻게 사용할 수 있습니까?

Connector / J에서 4 바이트 UTF8을 사용하려면 character_set_server = utf8mb4로 MySQL 서버를 구성합니다. Connector / J는 연결 문자열에 characterEncoding이 설정 되지 않은 한 해당 설정을 사용 합니다 . 이것은 문자 집합의 자동 감지와 동일합니다.

열과 데이터베이스도 조정하십시오.

var1 varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL

다시 말하지만, MySQL 버전은 utf8mb4 지원을 위해 비교적 최신 버전이어야합니다.


내 다른 관련 게시물을 확인하십시오 : stackoverflow.com/questions/13748170/… . 대답 할 수 있다면이 질문에도 대답 한 것입니다. 다른 게시물에는 내가 한 일에 대한 자세한 내용이 있습니다.
CodeKingPlusPlus 2012

1
@CodeKingPlusPlus은 당신이 데이터베이스의 모든 변경이 utf8mb4여전히 사용하고있는 것 같습니다, utf8_general_ci..
Esailija

1
커넥터 / J와 함께 "SET 명칭을"하지 마 : dev.mysql.com/doc/connector-j/en/... Do not issue the query set names with Connector/J, as the driver will not detect that the character set has changed, and will continue to use the character set detected during the initial connection setup.
bcoughlan

1
DB 변경의 혼란을 처리하는 대신 BMP 외부에서 문자를 제거하려면 여기를 참조하십시오. stackoverflow.com/questions/4035562/…
Indigenuity

2
\ 경우 ProgramData \ MySQL은 \ MySQL 서버 5.7 \의 my.ini : 나는 위의 단계를 수행하지만 C의 문자 집합 서버 = utf8mb4을 변경할 때까지 해결되지 않은, 같은 문제가
fattah.safa

16

대체로 4 바이트가 필요한 기호를 저장하려면 characher-set 및 collation을 업데이트해야합니다 utf8mb4.

  1. 데이터베이스 테이블 / 열 : alter table <some_table> convert to character set utf8mb4 collate utf8mb4_unicode_ci
  2. 데이터베이스 서버 연결 ( 참조 )

# 2의 개발 환경에서 서버를 시작할 때 명령 줄에 매개 변수를 설정하는 것을 선호합니다. mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci


BTW에주의를 기울 커넥터 / J 행동SET NAMES 'utf8mb4':

커넥터 / J를 사용하여 쿼리 세트 이름을 발행하지 마십시오. 드라이버는 문자 세트가 변경되었음을 감지하지 않고 초기 연결 설정 중에 감지 된 문자 세트를 계속 사용합니다.

characterEncoding연결된 서버 인코딩을 재정의하므로 연결 URL에서 매개 변수를 설정하지 마십시오 .

클라이언트 측에서 자동으로 감지 된 인코딩을 재정의하려면 서버에 연결하는 데 사용되는 URL에서 characterEncoding 속성을 사용합니다.


15

이상하게, 나는 제거하기 것을 발견 &characterEncoding=UTF-8으로부터 것은 JDBC url유사한 문제로 나를 위해 트릭을했다.

내 속성에 따라

jdbc_url=jdbc:mysql://localhost:3306/dbName?useUnicode=true

나는 이것이 @Esailija가 위에서 말한 것을 지원한다고 생각합니다. 즉, 실제로 5.5 인 내 MySQL은 UTF-8 인코딩의 가장 좋아하는 맛을 파악하고 있습니다.

(참고, 나는 또한 InputStream내가 읽고 UTF-8있는 자바 코드를 지정하고 있는데, 아마 아프지 않을 것입니다) ...


어쩌면 useUnicode=true필요하지 않습니까? 내 경우에는 일을 유일하게 설정하는 것입니다 character_set_server=utf8mb4(RDS 매개 변수 그룹) 서버에 글로벌 및 NOT 은 JDBC URL의 모든 characterEncoding 데.
Joshua Davis

6

내 문제를 어떻게 해결했는지.

나는 가지고 있었다

?useUnicode=true&amp;characterEncoding=UTF-8

내 최대 절전 모드 jdbc 연결 URL에서 문자열 데이터 유형을 이전에 varchar였던 데이터베이스의 longtext로 변경했습니다.


색인 된 열이 필요하지 않고 상대적으로 작다면 훌륭하지만 모든 열에 대해이 트릭을 수행 할 수 있습니다
shareef

3

useUnicode=true&amp;characterEncoding=UTF-8jdbc URL에 줄 을 추가하십시오 .

귀하의 경우 데이터는 UTF-8인코딩을 사용하여 전송되지 않습니다 .


이것을 어떻게 추가합니까? 내 연결 문자열에서? 도움이된다면 Netbeans를 사용하고 있습니다.
CodeKingPlusPlus 2011

연결을 어떻게 만들고 있습니까?
JHS

DriverManager.getConnection ( "jdbc : mysql : // localhost : #### / [dbName]", [사용자 이름], [비밀번호]);
CodeKingPlusPlus

다음과 같이하십시오-DriverManager.getConnection ( "jdbc : mysql : // localhost : #### / [dbName]? useUnicode = true & amp; characterEncoding = UTF-8", [사용자 이름], [비밀번호]);
JHS

1
스크래치, 나는 '?'를 잊었다. 하지만 지금은 원래 게시물과 동일한 오류로 돌아갑니다 ...
CodeKingPlusPlus

3

나는 같은 문제에 직면하고 각 열에 대해 Collationutf8_general_ci 로 설정하여 해결했습니다 .


2

MySQL은 이것이 유효한 UTF8 텍스트라고 믿지 않는다고 생각합니다. 동일한 열 정의 (mysql 클라이언트 연결도 UTF8)로 테스트 테이블에 삽입을 시도했지만 삽입했지만 MySQL CLI 클라이언트와 JDBC로 검색 한 데이터는 값을 올바르게 검색하지 못했습니다. UTF8이 올바르게 작동하는지 확인하기 위해 오바마에 "o"대신 "ö"를 삽입했습니다.

johan@maiden:~$ mysql -vvv test < insert.sql 
--------------
insert into utf8_test values(_utf8 "walmart öbama 👽💔")
--------------

Query OK, 1 row affected, 1 warning (0.12 sec)

johan@maiden:~$ file insert.sql 
insert.sql: UTF-8 Unicode text

테스트 할 작은 Java 애플리케이션 :

package test.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Test
{

    public static void main(String[] args)
    {
        System.out.println("test string=" + "walmart öbama 👽💔");
        String url = "jdbc:mysql://hostname/test?useUnicode=true&characterEncoding=UTF-8";
        try
        {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection c = DriverManager.getConnection(url, "username", "password");
            PreparedStatement p = c.prepareStatement("select * from utf8_test");
            p.execute();
            ResultSet rs = p.getResultSet();
            while (!rs.isLast())
            {
                rs.next();
                String retrieved = rs.getString(1);
                System.out.println("retrieved=\"" + retrieved + "\"");

            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

}

산출:

johan@appel:~/workspaces/java/javatest/bin$ java test.sql.Test
test string=walmart öbama 👽💔
retrieved="walmart öbama "

또한 JDBC 연결로 동일한 삽입을 시도했으며 동일한 예외가 발생했습니다. 나는 이것이 MySQL 버그라고 생각합니다. 이미 그런 상황에 대한 버그 리포트가 있을지도 ..


그건 그렇고, 문자열의 문자는 OSX의 Firefox와 Chrome 모두에서 올바르게 표시되지 않습니다. 내 iTerm 응용 프로그램에 올바르게 표시됩니다. 나는 이것이 글꼴에 따라 다르다고 생각합니다.
Friek dec.

1

나는 똑같은 문제가 있었고 모든 문자 세트에 대해 신중하게 살펴보고 그들이 괜찮다는 것을 알게 된 후, 내 클래스에 있던 버그가있는 속성이 @JoinColumn (javax.presistence; hibernate) 대신 @Column으로 주석 처리되었음을 깨달았습니다. 그것은 모든 것을 깨뜨리고있었습니다.


1

실행하다

show VARIABLES like "%char%”;

utf8mb4가 아닌 경우 문자 세트 서버를 찾으십시오.

my.cnf에 설정하십시오.

vim /etc/my.cnf

한 줄 추가

character_set_server = utf8mb4

마지막으로 mysql을 다시 시작하십시오.


1
character_set_server옵션이 아닙니다.character-set-server
Arun SR

0

이 설정 useOldUTF8Behavior = true는 저에게 잘 작동했습니다. 잘못된 문자열 오류는 없지만 Ã와 같은 특수 문자를 여러 문자로 변환하여 데이터베이스에 저장했습니다.

이러한 상황을 피하기 위해 JDBC 매개 변수에서이 속성을 제거하고 대신 내 열의 데이터 유형을 BLOB로 변환했습니다. 이것은 완벽하게 작동했습니다.


답변에 더 자세한 내용을 추가해 주시겠습니까? (코드, 명령 등)
aBnormaLz

-2

게다가 데이터 유형은 varchar 또는 텍스트의 blob 설치를 사용할 수 있습니다.


당신은 그것을 원하지 않습니다
ECostello
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.