我有脏数据.有时它包含像
this这样的字符.我使用这个数据来进行查询
WHERE a.address IN ('mydatahere')
对于这个角色我得到
org.hibernate.exception.GenericJDBCException: Illegal mix of collations (utf8_bin,IMPLICIT),(utf8mb4_general_ci,COERCIBLE),COERCIBLE) for operation ‘ IN ‘
如何过滤这样的字符?我使用Java.
谢谢.
解决方法
当我遇到这样的问题时,我使用Perl脚本来确保使用如下代码将数据转换为有效的UTF-8:
use Encode; binmode(STDOUT,":utf8"); while (<>) { print Encode::decode('UTF-8',$_); }
该脚本在stdin上占用(可能已损坏)UTF-8,并将有效的UTF-8重新打印到stdout.无效字符被替换为 (U FFFD,Unicode replacement character).
如果您在良好的UTF-8输入上运行此脚本,输出应与输入相同.
如果您在数据库中有数据,使用DBI扫描表格并使用此方法清理所有数据,以确保所有内容都是有效的UTF-8是有意义的.
这是同一脚本的Perl一线版本:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt
这是一个在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: Пр?вет } }