¿Cómo corregir los errores de "Valor de cadena incorrecto"?
Después de notar que una aplicación tendía a descartar correos electrónicos aleatorios debido a errores de valores de cadena incorrectos, cambié muchas columnas de texto para usar el utf8
conjunto de caracteres de columna y la clasificación de columna predeterminada ( utf8_general_ci
) para que los aceptara. Esto solucionó la mayoría de los errores e hizo que la aplicación dejara de recibir errores de SQL también cuando llegaba a correos electrónicos no latinos.
A pesar de esto, algunos de los correos electrónicos todavía hacen que el programa genere errores de valores de cadena incorrectos:(Incorrect string value: '\xE4\xC5\xCC\xC9\xD3\xD8...' for column 'contents' at row 1)
La columna de contenido es un MEDIUMTEXT
tipo de datos que utiliza el utf8
juego de caracteres de la columna y la utf8_general_ci
clasificación de la columna. No hay indicadores que pueda alternar en esta columna.
Teniendo en cuenta que no quiero tocar ni mirar el código fuente de la aplicación a menos que sea absolutamente necesario:
- ¿Qué está causando ese error? (sí, sé que los correos electrónicos están llenos de basura aleatoria, pero pensé que utf8 sería bastante permisivo)
- ¿Cómo puedo arreglarlo?
- ¿Cuáles son los efectos probables de tal solución?
Una cosa que consideré fue cambiar a un varchar utf8 ([un número grande]) con el indicador binario activado, pero no estoy familiarizado con MySQL y no tengo idea de si esa solución tiene sentido.
ACTUALIZACIÓN a la siguiente respuesta:
Cuando se hizo la pregunta, "UTF8" en MySQL significaba utf8mb3
. Mientras tanto, utf8mb4
se agregó, pero que yo sepa, "UTF8" de MySQL no se cambió a significar utf8mb4
.
Eso significa que necesitarías poner específicamente "utf8mb4", si lo dices en serio (y deberías usar utf8mb4
)
Mantendré esto aquí en lugar de simplemente editar la respuesta, para dejar claro que todavía hay una diferencia al decir "UTF8".
Original
No sugeriría la respuesta de Richie, porque estás arruinando los datos dentro de la base de datos. No solucionaría su problema, sino que intentaría "ocultarlo" y no podría realizar operaciones esenciales de la base de datos con los datos basura.
Si encuentra este error, los datos que está enviando no están codificados en UTF-8 o su conexión no es UTF-8. Primero, verifique que la fuente de datos (un archivo, ...) realmente sea UTF-8.
Luego, verifique la conexión de su base de datos, debe hacer esto después de conectarse:
SET NAMES 'utf8mb4';
SET CHARACTER SET utf8mb4;
A continuación, verifica que las tablas donde se almacenan los datos tengan el juego de caracteres utf8mb4:
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`
;
Por último, verifique la configuración de su base de datos:
mysql> show variables like '%colla%';
mysql> show variables like '%charac%';
Si el origen, el transporte y el destino son utf8mb4, su problema desapareció;)
Los tipos utf-8 de MySQL en realidad no son utf-8 adecuados: solo usa hasta tres bytes por carácter y solo admite el plano multilingüe básico (es decir, sin emoji, sin plano astral, etc.).
Si necesita almacenar valores de planos Unicode superiores, necesita las codificaciones utf8mb4 .
La tabla y los campos tienen una codificación incorrecta; sin embargo, puedes convertirlos a 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;
"\xE4\xC5\xCC\xC9\xD3\xD8"
no es UTF-8 válido. Probado usando Python:
>>> "\xE4\xC5\xCC\xC9\xD3\xD8".decode("utf-8")
...
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data
Si está buscando una manera de evitar errores de decodificación dentro de la base de datos, la codificación cp1252 (también conocida como "Windows-1252", también conocida como "Windows Western European") es la codificación más permisiva que existe: cada valor de byte es un punto de código válido.
Por supuesto, ya no entenderá UTF-8 genuino, ni ninguna otra codificación que no sea cp1252, pero parece que eso no le preocupa demasiado.