sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo evitar los caracteres basura/basura al leer datos de varios idiomas?

El gujarati comienza રેલવે , ¿correcto? Y el Malyalam comienza നേപ , ¿correcto? Y el inglés debería haber incluido Bureau’s .

Este es el caso clásico de

  • Los bytes que tiene en el cliente están codificados correctamente en utf8. (Bureau está codificado en el subconjunto Ascii/latin1 de utf8; pero no es el apóstrofe ascii.)
  • Te conectaste con SET NAMES latin1 (o set_charset('latin1') o ...), probablemente por defecto. (Debería haber sido utf8 .)
  • La columna en la tabla fue declarada CHARACTER SET latin1 . (O posiblemente se heredó de la tabla/base de datos). (Debería haber sido utf8 .)

La solución para los datos es una "ALTERACIÓN de 2 pasos".

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;

donde las longitudes son lo suficientemente grandes y los otros "..." tienen cualquier otra cosa (NOT NULL , etc) ya estaba en la columna.

Desafortunadamente, si tiene muchas columnas con las que trabajar, necesitará muchos ALTER. Puedes (debes) MODIFY todas las columnas necesarias para VARBINARY para una sola tabla en un par de ALTERs .

La corrección del código es establecer utf8 como la conexión; esto depende de la API utilizada en PHP. Los ALTERs cambiará la definición de la columna.

Editar

Tienes VARCHAR con el CHARACTER SET incorrecto . Por lo tanto, ves Mojibake como રેલ . La mayoría de las técnicas de conversión intentan preservar રેલ , pero eso no es lo que necesitas. En cambio, dar un paso hacia VARBINARY conserva los bits mientras ignora la definición anterior de los bits que representan caracteres codificados en latin1. El segundo paso nuevamente conserva los bits, pero ahora afirma que representan caracteres utf8.