Страдате от "двойно кодиране".
Ето какво се случи.
- Клиентът имаше символи, кодирани като utf8; и
SET NAMES latin1
излъга, като твърди, че клиентът има кодиране latin1; и- Колоната в таблицата е декларирана
CHARACTER SET utf8
.
Нека разгледаме какво се случва с e-acute:é
.
- Hex за това в utf8 е 2 байта:
C3A9
. SET NAMES latin1
видя го като 2 знака, кодирани с latinica1Ã
и©
(шестнадесетичен:C3
иA9
)- Тъй като целта беше
CHARACTER SET utf8
, тези 2 знака трябваше да бъдат преобразувани.Ã
беше преобразуван в utf8 (шестнадесетиченC383
) и©
(шестнадесетиченC2A9
) - И така, 4 байта бяха съхранени (шестнадесетичен
C383C2A9
)
Когато го прочете обратно, бяха извършени обратните стъпки и крайният потребител вероятно не забеляза нищо лошо. Какво не е наред:
- Съхранените данни са 2 пъти по-големи, отколкото трябва да бъдат (3 пъти за азиатски езици).
- Сравненията за равно, по-голямо от и т.н. може да не работят според очакванията.
ORDER BY
може да не работи според очакванията.
Нещо подобно ще поправи вашите данни:
UPDATE ... SET col = CONVERT(BINARY(CONVERT(
CONVERT(UNHEX(col) USING utf8)
USING latin1)) USING utf8);
Още дискусия иОще примери за поправяне