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

¿Cómo eliminar los caracteres incorrectos que no son adecuados para la codificación utf8 en MySQL?

Cuando tuve un problema como este, usé el script Perl para asegurar que los datos se conviertan a UTF-8 válido usando un código como este:

use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
    print Encode::decode('UTF-8', $_);
}

Este script toma (posiblemente corrupto) UTF-8 en stdin y vuelve a imprimir UTF-8 válido en stdout . Los caracteres no válidos se reemplazan con (U+FFFD , Carácter de reemplazo Unicode ).

Si ejecuta este script en una buena entrada UTF-8, la salida debería ser idéntica a la entrada.

Si tiene datos en la base de datos, tiene sentido usar DBI para escanear su(s) tabla(s) y borrar todos los datos usando este enfoque para asegurarse de que todo sea UTF-8 válido.

Esta es la versión Perl de una sola línea de este mismo script:

perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt

EDITAR:Se agregó una solución solo para Java .

Este es un ejemplo de cómo hacer esto en Java:

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;

public class UtfFix {
    public static void main(String[] args) throws InterruptedException, CharacterCodingException {
        CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
        decoder.onMalformedInput(CodingErrorAction.REPLACE);
        decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
        ByteBuffer bb = ByteBuffer.wrap(new byte[] {
            (byte) 0xD0, (byte) 0x9F, // 'П'
            (byte) 0xD1, (byte) 0x80, // 'р'
            (byte) 0xD0,              // corrupted UTF-8, was 'и'
            (byte) 0xD0, (byte) 0xB2, // 'в'
            (byte) 0xD0, (byte) 0xB5, // 'е'
            (byte) 0xD1, (byte) 0x82  // 'т'
        });
        CharBuffer parsed = decoder.decode(bb);
        System.out.println(parsed);
        // this prints: Пр?вет
    }
}