sql >> データベース >  >> RDS >> Mysql

MySQLのutf8エンコーディングに適していない不正な文字を削除するにはどうすればよいですか?

    このような問題が発生したときは、Perlスクリプトを使用して、次のようなコードを使用してデータが有効なUTF-8に変換されるようにしました。

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

    このスクリプトは、stdinでUTF-8を使用します(破損している可能性があります)。 有効なUTF-8をstdoutに再印刷します 。無効な文字はに置き換えられます (U+FFFDユニコード置換文字

    このスクリプトを適切なUTF-8入力で実行する場合、出力は入力と同じである必要があります。

    データベースにデータがある場合は、DBIを使用してテーブルをスキャンし、このアプローチを使用してすべてのデータをスクラブして、すべてが有効なUTF-8であることを確認するのが理にかなっています。

    これは、この同じスクリプトのPerlワンライナーバージョンです:

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

    編集:Javaのみのソリューションを追加

    これは、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: Пр?вет
        }
    }
    


    1. MySQLトリガーの質問:列が変更されたときにのみトリガーしますか?

    2. MySQLエラー:2013、「初期通信パケットの読み取り」でMySQLサーバーへの接続が失われました、システムエラー:0

    3. PHP-ページネーションを使用したMySQLクエリ

    4. Django管理者MySQL低速内部結合