“잘못된 문자열 값”오류를 수정하는 방법?


162

잘못된 문자열 값 오류로 인해 응용 프로그램이 임의의 전자 메일을 삭제하는 경향이 있음을 알았지 만 많은 문자 열을 utf8열 문자 세트와 기본 열 콜 레이션 ( utf8_general_ci) 을 사용하도록 전환 하여 허용했습니다. 이로 인해 대부분의 오류가 해결되었으며 비 라틴 전자 메일에 부딪히면 응용 프로그램에서 SQL 오류가 발생하지 않습니다.

그럼에도 불구하고 일부 이메일은 여전히 ​​프로그램이 잘못된 문자열 값 errrors에 도달하도록합니다. (Incorrect string value: '\xE4\xC5\xCC\xC9\xD3\xD8...' for column 'contents' at row 1)

내용 열은 열 문자 MEDIUMTEXT집합과 열 조합을 사용 하는 데이터 형식입니다 . 이 열에서 토글 할 수있는 플래그가 없습니다.utf8utf8_general_ci

절대적으로 필요한 경우가 아니면 응용 프로그램 소스 코드를 만지거나 보지 않으려는 것을 명심하십시오.

  • 그 오류의 원인은 무엇입니까? (예, 이메일에 임의의 쓰레기가 가득 차 있다는 것을 알고 있지만 utf8은 꽤 관대하다고 생각했습니다)
  • 어떻게 고칠 수 있습니까?
  • 그러한 수정의 영향은 무엇입니까?

내가 생각한 것 중 하나는 바이너리 플래그를 켜고 utf8 varchar ([일부 큰 숫자])로 바꾸는 것이지만 MySQL에 익숙하지 않으며 그러한 수정이 의미가 있는지 전혀 모른다.


3
사후 : RichieHindle의 솔루션 은 문제를 해결했으며 실행 시간에 추가 문제를 일으키지 않았습니다. 그것은 약간의 해킹 일 수도 있었지만 효과가 있었으며 완전히 이해하지 못하는 타사 소프트웨어로 인해 손이 더러워지는 것을 피할 수있었습니다. 이 시점에서 우리는 이러한 모든 인코딩 문제를 올바르게 처리하고 실제로 지원할 수있는 새로운 버전의 소프트웨어 / 스키마로 업데이트하여 해킹을 불필요하게 만듭니다.
Brian

답변:


43

"\xE4\xC5\xCC\xC9\xD3\xD8"유효한 UTF-8이 아닙니다. 파이썬을 사용하여 테스트 :

>>> "\xE4\xC5\xCC\xC9\xD3\xD8".decode("utf-8")
...
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data

데이터베이스 내에서 디코딩 오류를 피하는 방법을 찾고 있다면 cp1252 인코딩 (일명 "Windows-1252", "Windows Western European")이 가장 허용되는 인코딩입니다. 모든 바이트 값은 유효한 코드 포인트입니다.

물론 더 이상 진짜 UTF-8이나 다른 비 CP1252 인코딩을 이해하지 못하지만 너무 걱정하지 않는 것처럼 들립니까?


4
"물론 더 이상 진정한 UTF-8을 이해하지 못할 것입니까?"
Brian

5
@Brian : cp1252를주고 있다고 말하면 실제로 UTF-8을 제공합니다. 예를 들어, café으로 잘못 해석합니다 café. 충돌하지는 않지만 높은 비트 문자를 오해합니다.
RichieHindle

3
@Richie : 데이터베이스는 원하는대로 데이터를 행복하게 호출 할 수 있지만 PHP 코드를 가져 오는 문자열에 문자열을 채우면 큰 차이가 없습니다 ... 그렇습니까? UTF-8에 대한 이해 부족이 어디에 영향을 미치는지 정확히 알지 못합니다.
Brian

7
@ 브라이언 : 아뇨, 당신 말이 맞아요. 예를 들어 SQL에서 ORDER BY 절을 사용한 경우 차이가 발생하는 시간은 데이터베이스 내에있을 것입니다. ASCII가 아닌 문자가 있으면 정렬이 어려워집니다.
RichieHindle

11
이 답변을 해결책으로 표시하지 마십시오. 오류를 숨기는 것은 해결책이 아닙니다. 차에서 과열 램프를 제거하면 알 수 있습니다.
David Vartanian

133

데이터베이스 내부의 데이터를 망쳐 놓고 있기 때문에 Richies의 대답을 제안하지 않습니다. 문제점을 수정하지는 않지만 문제점을 "숨기려고"하고 랩된 데이터로 필수 데이터베이스 조작을 수행 할 수 없습니다.

이 오류가 발생하면 전송중인 데이터가 UTF-8로 인코딩되지 않았거나 연결이 UTF-8이 아닙니다. 먼저 데이터 소스 (파일, ...)가 실제로 UTF-8인지 확인하십시오.

그런 다음 데이터베이스 연결을 확인하십시오. 연결 한 후에이 작업을 수행해야합니다.

SET NAMES 'utf8';
SET CHARACTER SET utf8;

다음으로, 데이터가 저장된 테이블에 utf8 문자 세트가 있는지 확인하십시오.

SELECT
  `tables`.`TABLE_NAME`,
  `collations`.`character_set_name`
FROM
  `information_schema`.`TABLES` AS `tables`,
  `information_schema`.`COLLATION_CHARACTER_SET_APPLICABILITY` AS `collations`
WHERE
  `tables`.`table_schema` = DATABASE()
  AND `collations`.`collation_name` = `tables`.`table_collation`
;

마지막으로 데이터베이스 설정을 확인하십시오.

mysql> show variables like '%colla%';
mysql> show variables like '%charac%';

소스, 전송 및 대상이 UTF-8이면 문제가 해결 된 것입니다.)


1
@Kariem :이 설정은 SET character_set_client, SET character_set_results, SET character_set_connection dev.mysql.com/doc/refman/5.1/en/charset-connection.html
니코가 웬다

2
두 번째 명령은해야한다 SET CHARACTER SET utf8(안 character_set에)
코더

6
이 답변은 문제를 조사하는 데 도움이되지만 문제를 해결하기 위해 수행 할 작업에는 답변하지 않습니다. "utf-8"대신 "latin1"이 표시됩니다.
Vanuan

2
이 답변은 문제를 설명하는 데는 좋지만 솔루션을 자세하게 설명하는 데는 매우 좋지 않습니다 (OP가 요청한 것임). @ nicogawenda : 문제를 완전히 해결하기 위해 실행할 모든 SQL 쿼리는 무엇입니까? 기존 데이터를 모두 수정하는 방법?
클린트 이스트우드

1
"소스, 교통 및 대상이 UTF-8 인 경우, 문제는 사라입니다)"는 나를 위해 속임수였습니다
suarsenegger

80

MySQL의 utf-8 유형은 실제로 적절한 utf-8이 아닙니다. 문자 당 최대 3 바이트 만 사용하며 기본 다국어 평면 (이모 지, 아스트랄 평면 등) 만 지원합니다.

더 높은 유니 코드 평면의 값을 저장해야하는 경우 utf8mb4 인코딩 이 필요합니다 .


9
이것이 가장 좋은 해결책이라고 생각합니다. 위의 답변에서 5.5로 업그레이드하고 utf8을 utf8mb4로 바꿉니다. 트위터에서 4 바이트가 필요한 이모티콘이나 다른 문자가있는 utf8 데이터를 삽입하고있었습니다.
rmarscher

5.5로 업그레이드하지 않을 것입니다. 오류를 어떻게 억제합니까?
사용자

이 가장 유용한 답변을보기에는 너무 멀리 스크롤했습니다.
휴대용 핸드 헬드

1
원래 질문 이후 10 년. MySQL의 utf8 인코딩이 적절한 utf8이 아니라는 것을 알 수 있습니다. utf8mb4를 사용하십시오! MariaDB도 마찬가지입니다. 그렇지 않으면 당신은 기쁨의 눈물을 가질 수 없습니다 😂
Liam

51

테이블과 필드의 인코딩이 잘못되었습니다. 그러나 UTF-8로 변환 할 수 있습니다.

ALTER TABLE logtest CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE logtest DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE logtest CHANGE title title VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci;

1
나는 이것이 모두의 정답이라고 생각합니다. 두 개의 테이블에 각각 utf8 varchar 형식이 있습니다. 하나는 오류가 있고 다른 하나는 괜찮습니다. 사용자 'update select'조차도 'good'utf8 열에서 다른 테이블로 복사하면 동일한 오류가 발생합니다. 두 테이블이 서로 다른 버전의 MySQL에서 생성되기 때문입니다.
AiShiguang

예! 내 데이터베이스 테이블에서 잘못 구성되었습니다. 나는이 답변이 정답이라고 생각합니다. 내 문제는 선택한 collate가 utf8_general_ci 대신 utf8_unicode_ci라는 것입니다. 감사합니다 :)
jprivillaso

2
여기에이 대답을하고 무엇 상단에 있어야합니다
Sagun 쉬 레스타

1
이것은 도움이 될 수 있습니다. 무엇이 잘못되었는지 대신에 무엇을 시도해야하는지 알려줍니다.
Victor Di

감사합니다! 그것은 단지 내가 생각했던 테이블 콜 레이션 개미를 변경했지만 많은 도움이되었지만 필드는 여전히 ASCII 콜 레이션이었습니다 ...
Radu

25

오늘 UTF-8 문자 대신 원시 바이트를 저장하는 'LONGBLOB'유형으로 열을 변경 하여이 문제를 해결했습니다.

이 작업의 유일한 단점은 인코딩을 직접 관리해야한다는 것입니다. 응용 프로그램의 한 클라이언트가 UTF-8 인코딩을 사용하고 다른 클라이언트가 CP1252를 사용하는 경우 전자 메일이 잘못된 문자로 전송 될 수 있습니다. 이를 피하려면 모든 애플리케이션 에서 항상 동일한 인코딩 (예 : UTF-8)을 사용하십시오 .

TEXT / LONGTEXT와 BLOB / LONGBLOB의 차이점에 대한 자세한 내용은 이 페이지 http://dev.mysql.com/doc/refman/5.0/en/blob.html 을 참조하십시오. 웹에서이 두 가지를 논의하는 다른 주장들도 많이 있습니다.


1
이 솔루션은 가장 쉬운 방법으로 보입니다. 나는 성공하지 않고 다른 인코딩을 거의 시도하지 않았습니다.
Simeon Abolarinwa

10

먼저 default_character_set_name이 utf8인지 확인하십시오.

SELECT default_character_set_name FROM information_schema.SCHEMATA S WHERE schema_name = "DBNAME";

결과가 utf8이 아닌 경우 데이터베이스를 변환해야합니다. 처음에는 덤프를 저장해야합니다.

지정된 데이터베이스의 모든 테이블에 대해 문자 세트 인코딩을 UTF-8로 변경하려면 명령 행에 다음 명령을 입력하십시오. DBNAME을 데이터베이스 이름으로 바꾸십시오.

mysql --database=DBNAME -B -N -e "SHOW TABLES" | awk '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' | mysql --database=DBNAME

데이터베이스 자체에서 문자 세트 인코딩을 UTF-8로 변경하려면 mysql > 프롬프트 에서 다음 명령을 입력하십시오 . DBNAME을 데이터베이스 이름으로 바꾸십시오.

ALTER DATABASE DBNAME CHARACTER SET utf8 COLLATE utf8_general_ci;

이제 데이터베이스에 utf8 문자를 쓰려고 다시 시도 할 수 있습니다. 이 솔루션은 데이터베이스에 200000 행의 CSV 파일을 업로드하려고 할 때 도움이됩니다.


8

일반적으로 인코딩 / 콜 레이션이 호환되지 않는 열에 문자열을 삽입 할 때 발생합니다.

TRIGGER가있을 때이 오류가 발생하여 어떤 이유로 서버의 데이터 정렬을 상속합니다. 그리고 mysql의 기본값은 스웨덴어 데이터 정렬이있는 (적어도 우분투에서는) latin-1입니다. 데이터베이스와 모든 테이블을 UTF-8로 설정했지만 아직 설정하지 않았습니다 my.cnf.

/etc/mysql/my.cnf :

[mysqld]
character-set-server=utf8
default-character-set=utf8

그리고 이것은 모든 트리거를 utf8- *로 나열해야합니다.

select TRIGGER_SCHEMA, TRIGGER_NAME, CHARACTER_SET_CLIENT, COLLATION_CONNECTION, DATABASE_COLLATION from information_schema.TRIGGERS

그리고 여기에 나열된 변수 중 일부에는 utf-8- *가 있어야합니다 (라틴어 -1 또는 다른 인코딩 없음).

show variables like 'char%';

6

데이터 정렬이 utf8_general_ci로 설정되어 있지만 데이터베이스, 테이블 또는 열의 문자 인코딩이 다를 수 있습니다.

ALTER TABLE tabale_name MODIFY COLUMN column_name VARCHAR(255)  
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;

5

비슷한 오류가 발생했습니다 ( Incorrect string value: '\xD0\xBE\xDO\xB2. ...' for 'content' at row 1). 열의 문자 세트를로 변경하려고 시도했지만 utf8mb4그 후에 오류가로 변경되었습니다 'Data too long for column 'content' at row 1'.
mysql에서 잘못된 오류가 표시되는 것으로 나타났습니다. 열의 문자 집합을로 utf8바꾸고 열 유형을로 변경했습니다 MEDIUMTEXT. 그 후 오류가 사라졌습니다.
누군가에게 도움이되기를 바랍니다.
그건 그렇고 MariaDB (동일한 INSERT를 테스트했습니다)는 오류없이 텍스트를 자릅니다.


MySQL도 너무 피곤해서 mysql 이이 버전에서 4 바이트 utf-8 uncoding을 지원하지 않으며이 원인을 이해하려고 노력하고 있음을 깨달았습니다. 유형을 변경하는 것이 바로 해결책이었습니다.
Liza

4

이 오류는 인코딩이 잘못된 문자열이 있거나 (예 : UTF-8로 인코딩 된 열에 ISO-8859-1로 인코딩 된 문자열을 입력하려고 함) 열이 입력하려는 데이터를 지원하지 않음을 의미합니다.

실제로 후자의 문제는 UTF-8로 표현 될 때 1-3 바이트가 필요한 유니 코드 문자 만 지원하는 MySQL UTF-8 구현으로 인해 발생합니다. JDBC를 통해 MySQL에 UTF-8을 삽입하려고 할 때 "잘못된 문자열 값"을 참조하십시오 . 자세한 내용은.


2

이 잘못된 문자열 값을 실행할 때 나를위한 해결책 : scriptcase를 사용하는 열 오류의 경우 '\ xF8'은 데이터베이스가 utf8 일반 ci에 대해 설정되어 있고 필드 정렬도 설정되어 있는지 확인하는 것이 었습니다. 그런 다음 csv 파일의 데이터 가져 오기를 수행 할 때 csv를 UE Studio에로드 한 다음 utf8 및 Voila 형식으로 저장합니다! 그것은 매력처럼 작동합니다 .29000의 오류가 없습니다. 이전에는 Excel에서 만든 CSV를 가져 오려고했습니다.


2

나는 위의 모든 해결책을 시도했지만 (모두 유효한 점을 가져옴) 아무것도 효과가 없었습니다.

C #의 MySQL 테이블 필드 매핑이 잘못된 유형 MySqlDbType.Blob을 사용하고 있음을 알 때까지 . MySqlDbType.Text로 변경 했으며 이제 원하는 모든 UTF8 기호를 쓸 수 있습니다!

ps My MySQL 테이블 필드는 "LongText"유형입니다. 그러나 MyGeneration 소프트웨어를 사용하여 필드 매핑을 자동 생성하면 C #에서 필드 유형이 MySqlDbType.Blob으로 자동 설정됩니다.

흥미롭게도 언젠가는 몇 달 동안 UTF8 문자가있는 MySqlDbType.Blob 유형을 문제없이 사용하고 있었지만 언젠가는 특정 문자가 포함 된 문자열을 작성하려고 시도했습니다.

이것이 오류의 원인을 찾는 데 어려움을 겪고있는 사람에게 도움이되기를 바랍니다.


1

열 이름 앞에 이진을 추가하고 문자 집합 오류를 해결했습니다.

tableA 값에 삽입하십시오 (이진 문자열 colname1);


1

안녕하세요, godaddy 서버에서 온라인 데이터베이스를 사용할 때이 오류가 발생했습니다 .MySQL 버전이 5.1 이상이라고 생각합니다. 하지만 내 로컬 호스트 서버 (버전 5.7)에서 할 때 로컬 서버에서 테이블을 만들고 mysql yog를 사용하여 온라인 서버에 복사 한 후에 문제가 없었습니다. 문제는 문자 세트에 있다고 생각합니다.

여기 스크린 샷


1

이 오류를 해결하기 위해 MySQL 데이터베이스를 utf8mb4로 업그레이드 하여이 자세한 자습서를 따라 전체 유니 코드 문자 집합을 지원합니다 . 필자는 약간의 문제가 있기 때문에 신중하게 검토하는 것이 좋습니다 (예 : 필드 유형을 수정 해야하는 새로운 인코딩으로 인해 색인 키가 너무 커질 수 있음).


1

여기에 좋은 답변이 있습니다. 나는 같은 오류가 발생하여 내 것을 추가하고 있지만 완전히 다른 문제로 판명되었습니다. (표면에 동일하지만 근본 원인이 다를 수 있습니다.)

나에게 다음 필드에서 오류가 발생했습니다.

@Column(nullable = false, columnDefinition = "VARCHAR(255)")
private URI consulUri;

결국 URI클래스 의 이진 직렬화로 데이터베이스에 저장됩니다 . 이것은 단위 테스트 (H2 사용) 또는 CI / 통합 테스트 ( MariaDB4j 사용 )에서 플래그를 발생시키지 않았으며 프로덕션과 같은 설정에서 폭발했습니다. (문제를 이해 한 후에는 MariaDB4j 인스턴스에서 잘못된 값을 쉽게 확인할 수 있었지만 테스트는 중단되지 않았습니다.) 솔루션은 사용자 정의 유형 매퍼를 빌드하는 것이 었습니다.

package redacted;

import javax.persistence.AttributeConverter;
import java.net.URI;
import java.net.URISyntaxException;

import static java.lang.String.format;

public class UriConverter implements AttributeConverter<URI, String> {
    @Override
    public String convertToDatabaseColumn(URI attribute) {
        return attribute.toString();
    }

    @Override
    public URI convertToEntityAttribute(String field) {
        try {
            return new URI(field);
        }
        catch (URISyntaxException e) {
            throw new RuntimeException(format("could not convert database field to URI: %s", field));
        }
    }
}

다음과 같이 사용됩니다 :

@Column(nullable = false, columnDefinition = "VARCHAR(255)")
@Convert(converter = UriConverter.class)
private URI consulUri;

Hibernate가 관여하는 한, for를 포함하여 제공java.net.URL 되지 않은 type mappers 가있는 것처럼 보이지만 java.net.URI(여기서는 우리가 필요로 한 것입니다).


1

필자의 경우이 문제는 Mysql 열 인코딩을 'binary'로 변경하여 해결되었습니다 (데이터 유형은 VARBINARY로 자동 변경됩니다). 아마도 해당 열로 필터링하거나 검색 할 수는 없지만 그럴 필요는 없습니다.


1

저장하기 전에 일부 문자열 함수로 값을 처리하는 경우 함수가 멀티 바이트 문자를 올바르게 처리 할 수 ​​있는지 확인하십시오. 이를 수행 할 수없고 자르려고 시도하는 문자열 함수는 중간에 단일 멀티 바이트 문자 중 하나를 분할 할 수 있으며 이러한 문자열 오류 상황이 발생할 수 있습니다.

예를 들어 PHP에서는에서 substr로 전환해야 합니다 mb_substr.


0

제 경우에는 먼저 '???'를 만났습니다. 내 웹 사이트에서 라틴 문자 인 Mysql의 문자 세트를 확인하십시오. 따라서 utf-8로 변경 한 다음 프로젝트를 다시 시작하면 동일한 오류가 발생합니다. 데이터베이스의 문자 세트를 변경하는 것을 잊어 버렸습니다. 그리고 utf-8, 붐으로 바뀌 었습니다.


0

나는 여기에 언급 된 거의 모든 단계를 시도했습니다. 아무도 효과가 없었습니다. mariadb를 다운로드했습니다. 효과가있었습니다. 나는 이것이 해결책이 아니라는 것을 알고 있습니다. 누군가가 문제를 빨리 식별하거나 임시 해결책을 제시하는 데 도움이 될 수 있습니다.

Server version: 10.2.10-MariaDB - MariaDB Server
Protocol version: 10
Server charset: UTF-8 Unicode (utf8)

0

제 경우 Incorrect string value: '\xCC\x88'...에는 문제는 o- 움라우트가 분해 된 상태라는 것입니다. 이 질문과 대답은 나를 사이의 차이 이해하는 데 도움 ö. PHP에서 나를위한 해결책은 PHP의 Normalizer 라이브러리 를 사용하는 것이 었습니다 . 예, Normalizer::normalize('o¨', Normalizer::FORM_C).


-2

1-UTF8을 enconding하는 속성을 연결에 선언해야합니다. http://php.net/manual/en/mysqli.set-charset.php .

2-mysql commando line을 사용하여 스크립트를 실행하는 경우 다음과 같이 플래그를 사용해야합니다. Cmd: C:\wamp64\bin\mysql\mysql5.7.14\bin\mysql.exe -h localhost -u root -P 3306 --default-character-set=utf8 omega_empresa_parametros_336 < C:\wamp64\www\PontoEletronico\PE10002Corporacao\BancoDeDadosModelo\omega_empresa_parametros.sql

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