MySQL Преобразовать latin1 в utf8, cp1252 0x80-0x9F неправильно

Ситуация: База данных latin1 была сброшена как latin1, преобразована через iconv в utf8 и восстановлена ​​как utf8_unicode_ci.

Кажется, все преобразования прошли нормально, за исключением тех 0x80-0x9F из cp1252. я не совсем понял, что означает mysql, переводя эти символы в юникод: mysql:

latin1 — это набор символов по умолчанию. В MySQL latin1 совпадает с набором символов Windows cp1252. Это означает, что он такой же, как официальный ISO 8859-1 или IANA (Internet Assigned Numbers Authority) latin1, за исключением того, что IANA latin1 рассматривает кодовые точки между 0x80 и 0x9f как «неопределенные», тогда как cp1252 и, следовательно, MySQL latin1 присваивают символы для тех должностей. Например, 0x80 — это знак евро. Для «неопределенных» записей в cp1252 MySQL переводит 0x81 в Unicode 0x0081, 0x8d в 0x008d, 0x8f в 0x008f, 0x90 в 0x0090 и 0x9d в 0x009d.

Мои таблицы показывают, например, € 0xC280 вместо € 0x80. поэтому я думаю, что меня ввели в заблуждение, конвертируя через

iconv -f latin1 -t utf8

вместо этого я должен был преобразовать

iconv -f cp1252 -t utf-8

как показывают мои тесты. потому что вторая линия делает работу правильно.

Итак, вопрос в том, можно ли исправить эти плохие символы или мне нужно сбросить всю базу данных?

РЕДАКТИРОВАТЬ: возможно ли сбросить неверную базу данных и преобразовать ее через

  --default-character-set=utf8
  iconv -c -f utf-8 -t latin1
  iconv -f latin1 -t utf-8 

затем снова вставить в базу данных? Поможет ли мне iconv -c или я потеряю информацию?

EDIT2: кажется, что можно заменить сломанные символы один за другим, используя:

update history set note = replace(note,unhex('C280'),unhex('E282AC'));

это успешно заменит неправильный 2-байтовый glibberish правильным 3-байтовым utf8. конечно, это нужно сделать для каждого столбца varchar/text, а также для каждого сломанного символа в диапазоне 0x80-0x9F, что неудобно. Итак, надеюсь, у кого-то есть идея получше?


person gantners    schedule 16.10.2014    source источник


Ответы (1)


Насколько я понимаю, команда iconv основана на функции iconv C: http://www.gnu.org/software/libiconv/documentation/libiconv-1.11/iconv.3.html

Функция iconv возвращает количество символов, преобразованных необратимым образом во время этого вызова; обратимые превращения не учитываются. В случае ошибки он устанавливает errno и возвращает (size_t)(-1).

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

person Matzz    schedule 16.10.2014
comment
плохо, что у меня нет номера, так как я не напечатал код возврата :( как бы выглядел ваш бинарный подход? - person gantners; 17.10.2014
comment