Você sofre de "codificação dupla".
Aqui está o que aconteceu.
- O cliente tinha caracteres codificados como utf8; e
SET NAMES latin1
mentiu alegando que o cliente tinha codificação latin1; e- A coluna na tabela declarada
CHARACTER SET utf8
.
Vamos ver o que acontece com o e-acute:
é
. - O hex para isso, em utf8 é de 2 bytes:
C3A9
. SET NAMES latin1
vi como 2 caracteres codificados em latin1Ã
e©
(hex:C3
eA9
)- Como o destino era
CHARACTER SET utf8
, esses 2 caracteres precisavam ser convertidos.Ã
foi convertido para utf8 (hexC383
) e©
(hexC2A9
) - Então, 4 bytes foram armazenados (hex
C383C2A9
)
Ao lê-lo novamente, as etapas inversas foram executadas e o usuário final possivelmente não notou nada de errado. O que está errado:
- Os dados armazenados são 2 vezes maiores do que deveriam (3x para idiomas asiáticos).
- As comparações para igual, maior que etc. podem não funcionar como esperado.
ORDER BY
pode não funcionar como esperado.
Algo assim irá reparar seus dados:
UPDATE ... SET col = CONVERT(BINARY(CONVERT(
CONVERT(UNHEX(col) USING utf8)
USING latin1)) USING utf8);
Mais discussão eMais exemplos de como corrigi-lo