Как исправить ошибки "Неверное строковое значение"?

После того как вы заметили, что приложение отклоняло случайные письма из-за неправильных ошибок в строковых значениях, я пошел и переключил много текстовых столбцов, чтобы использовать кодировку столбца utf8 и столбец столбца по умолчанию (utf8_general_ci), чтобы он принимал их. Это фиксировало большинство ошибок и заставило приложение перестать получать sql-ошибки, когда оно попадает и в нелатинские электронные письма.

Несмотря на это, некоторые из сообщений электронной почты все еще заставляют программу удалять неверные ошибки строковых значений: (Incorrect string value: '\xE4\xC5\xCC\xC9\xD3\xD8...' for column 'contents' at row 1)

Столбец содержимого представляет собой MEDIUMTEXT datatybe, который использует колонку столбцов utf8 и столбец utf8_general_ci. В этом столбце нет флажков.

Помня о том, что я не хочу касаться или даже смотреть на исходный код приложения, если это абсолютно необходимо:

  • Что вызывает эту ошибку? (да, я знаю, что электронные письма полны случайного мусора, но я думал, что utf8 будет довольно разрешительным).
  • Как я могу это исправить?
  • Каковы вероятные последствия такого исправления?

Одна вещь, которую я рассматривал, это переход на utf8 varchar ([некоторое большое число]) с включенным двоичным флагом, но я довольно незнакомый с MySQL, и понятия не имею, имеет ли смысл такое исправление.

Ответ 1

"\xE4\xC5\xCC\xC9\xD3\xD8" недействителен UTF-8. Протестировано с помощью Python:

>>> "\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 "aka" Windows Western European) является наиболее разрешительной кодировкой - каждое значение байта является действительным кодовая точка.

Конечно, он больше не будет понимать подлинный UTF-8 или любую другую кодировку, отличную от cp1252, но похоже, что вы не слишком обеспокоены этим?

Ответ 2

Я бы не предложил Ричи ответить, потому что вы ввергаете данные в базу данных. Вы не исправите свою проблему, но попытаетесь "скрыть" ее и не сможете выполнять важные операции с данными с обломанными данными.

Если вы столкнулись с этой ошибкой, либо данные, которые вы отправляете, не закодированы в кодировке 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, ваша проблема исчезла;)

Ответ 3

MySQLs utf-8 типов на самом деле не являются правильными utf-8 - он использует только до трех байтов на символ и поддерживает только базовую многоязычную плоскость (т.е. не Emoji, астральная плоскость и т.д.).

Если вам нужно сохранить значения из более высоких планов Unicode, вам нужны коды utf8mb4.

Ответ 4

Таблица и поля имеют неправильную кодировку; однако вы можете преобразовать их в 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;

Ответ 5

Я решил эту проблему сегодня, изменив столбец на тип LONGBLOB, в котором хранятся необработанные байты вместо символов UTF-8.

Единственным недостатком этого является то, что вы должны сами позаботиться о кодировании. Если один клиент вашего приложения использует кодировку UTF-8, а другой использует CP1252, у вас могут быть отправлены ваши сообщения с неправильными символами. Чтобы избежать этого, всегда использует ту же кодировку (например, UTF-8) во всех ваших приложениях.

Обратитесь к этой странице http://dev.mysql.com/doc/refman/5.0/en/blob.html для получения более подробной информации о различиях между TEXT/LONGTEXT и BLOB/LONGBLOB. Есть много других аргументов в Интернете, обсуждающих эти два вопроса.

Ответ 6

В общем, это происходит, когда вы вставляете строки в столбцы с несовместимым кодированием/сопоставлением.

Я получил эту ошибку, когда у меня были TRIGGER, которые почему-то наследуют сортировку серверов. И mysql default (по крайней мере, на Ubuntu) латинский-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%';

Ответ 7

Сначала проверьте, является ли ваш 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

Несмотря на то, что для вашего сопоставления установлено значение utf8_general_ci, я подозреваю, что кодировка символов базы данных, таблицы или столбца может отличаться.

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

Ответ 9

Эта ошибка означает, что либо у вас есть строка с неправильным кодированием (например, вы пытаетесь ввести кодированную строку ISO-8859-1 в кодированный столбец UTF-8), либо столбец не поддерживает данные, которые вы пытаетесь для входа.

На практике последняя проблема вызвана реализацией MySQL UTF-8, которая поддерживает только символы UNICODE, которые нуждаются в 1-3 байтах, если они представлены в UTF-8. См. "Неправильное строковое значение" при попытке вставить UTF-8 в MySQL через JDBC? для деталей.

Ответ 10

Я получил аналогичную ошибку (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 там) просто вырезал текст без ошибок.

Ответ 11

Решение для меня при запуске в это неправильное строковое значение: '\ xF8' для ошибки столбца с использованием сценария должно было быть уверенным, что моя база данных настроена для utf8 general ci, а также мои сопоставления полей. Затем, когда я делаю импорт данных из файла csv, я загружаю csv в UE Studio, затем сохраняю его в формате utf8 и Voila! Он работает как шарм, 29000 записей там нет ошибок. Раньше я пытался импортировать созданный excel csv.

Ответ 12

Я пробовал все вышеперечисленные решения (которые все приносят действительные баллы), но для меня ничего не работало.

До тех пор, пока я не обнаружил, что мои сопоставления полей таблицы MySQL в С# использовали неправильный тип: MySqlDbType.Blob. Я изменил его на MySqlDbType.Text, и теперь я могу написать все символы UTF8, которые я хочу!

p.s. Поле My MySQL имеет тип LongText. Однако, когда я автогенерировал сопоставления полей с помощью программного обеспечения MyGeneration, он автоматически устанавливает тип поля как MySqlDbType.Blob в С#.

Интересно, что я использовал тип MySqlDbType.Blob с символами UTF8 в течение многих месяцев без каких-либо проблем, пока однажды не попытался написать строку с определенными символами в ней.

Надеюсь, это поможет кому-то, кто пытается найти причину ошибки.

Ответ 13

Я добавил двоичный код перед именем столбца и устранил ошибку charset.

вставить в значения tableA (двоичный stringcolname1);

Ответ 14

Привет, я также получил эту ошибку, когда я использую свои онлайн-базы данных с сервера godaddy Я думаю, что у него есть версия mysql 5.1 или более. но когда я делаю это с моего сервера localhost (версия 5.7), это было хорошо после того, как я создал таблицу с локального сервера и скопировал ее на онлайн-сервер с помощью mysql yog. Я думаю, что проблема связана с набором символов

Снимок экрана здесь

Ответ 15

Чтобы исправить эту ошибку, я обновил мою базу данных MySQL до utf8mb4, которая поддерживает полный набор символов Unicode, следуя этому подробному руководству. Я предлагаю внимательно изучить это, потому что есть довольно много ошибок (например, индексные ключи могут стать слишком большими из-за новых кодировок, после которых вам нужно изменить типы полей).

Ответ 16

Здесь хорошие ответы. Я просто добавляю мои, так как я столкнулся с той же ошибкой, но это оказалось совсем другой проблемой. (Возможно, на поверхности одно и то же, но другая коренная причина.)

Для меня произошла ошибка для следующего поля:

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

Это заканчивается тем, что хранится в базе данных как двоичная сериализация класса URI. Это не повышало флагов с модульным тестированием (с использованием H2) или CI/интеграционного тестирования (используя MariaDB4j), он взорвался наша производственная установка. (Хотя, как только проблема была понята, было достаточно легко увидеть неправильное значение в экземпляре MariaDB4j, это просто не взорвало тест.) Решение заключалось в создании настраиваемого типа mapper:

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, похоже, у него есть куча предоставленных типов mappers, в том числе для java.net.URL, но не для java.net.URI (это то, что нам нужно здесь).

Ответ 17

В моем случае, сначала я встречаю '???' на моем веб-сайте, тогда я проверяю набор символов Mysql, который теперь является латинским, поэтому я меняю его на utf-8, затем я перезапускаю проект, затем я получил ту же ошибку с вами, после чего я обнаружил, что забыл изменить кодировку базы данных и сменился на utf-8, стрела, он работал.

Ответ 18

Сначала я изменил тип столбца на LONG BLOB, вставил данные, а затем изменил тип столбца на VARCHAR (255), так как данные были не слишком чувствительны, я рискнул и тоже был огромен (около 40 тыс. Записей). Я предлагаю вам попробовать это, если только у вас нет данных, которые вы не хотите искажать.

Ответ 19

Я попробовал почти все шаги, упомянутые здесь. Никто не работал. Скачал мариадб. Это сработало. Я знаю, что это не решение, но это может помочь кому-то быстро определить проблему или дать временное решение.

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

Ответ 20

В моем случае эта проблема была решена путем изменения кодировки столбца Mysql на "двоичный" (тип данных будет автоматически изменен на VARBINARY). Возможно, я не смогу фильтровать или искать по этому столбцу, но мне это не нужно.

Ответ 21

1 - Вы должны объявить в своей связи правильность обращения к UTF8. http://php.net/manual/en/mysqli.set-charset.php.

2 - Если вы используете mysql commando line для выполнения script, вы должны использовать флаг, например: 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