emoji字符无法写入Mysql数据库问题
程序员文章站
2022-06-04 15:56:44
...
最近发现Kettle的ETL中一直在报错,查看日志发现有些字无法入库,类似以前遇到的数据源与目的数据库字段字符集不同导致的一样;但这个是从游戏接口日志文件读取的,字符集统一都是utf8,不应该是上述情况导致。错误日志如下
INFO 24-12 18:39:44,257 - Column types: string,smallint,string,string,string,string,int,string,string,string,string,string,string,string,string,int ERROR 24-12 18:39:45,281 - Table output - Because of an error, this step can't continue: ERROR 24-12 18:39:45,281 - Table output - org.pentaho.di.core.exception.KettleException: Error batch inserting rows into table [t_oper_mone_first_buy_fact]. Errors encountered (first 10): Incorrect string value: '\xF0\x9F\x91\x8D' for column 'f_char_name' at row 1 Error updating batch Incorrect string value: '\xF0\x9F\x91\x8D' for column 'f_char_name' at row 1 at org.pentaho.di.trans.steps.tableoutput.TableOutput.writeToTable(TableOutput.java:393) at org.pentaho.di.trans.steps.tableoutput.TableOutput.processRow(TableOutput.java:117) at org.pentaho.di.trans.step.RunThread.run(RunThread.java:40) at java.lang.Thread.run(Thread.java:662) Caused by: org.pentaho.di.core.exception.KettleDatabaseBatchException: Error updating batch Incorrect string value: '\xF0\x9F\x91\x8D' for column 'f_char_name' at row 1 at org.pentaho.di.trans.steps.tableoutput.TableOutput.writeToTable(TableOutput.java:309) ... 3 more Caused by: java.sql.BatchUpdateException: Incorrect string value: '\xF0\x9F\x91\x8D' for column 'f_char_name' at row 1 at com.mysql.jdbc.ServerPreparedStatement.executeBatchSerially(ServerPreparedStatement.java:796) at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1449) at org.pentaho.di.trans.steps.tableoutput.TableOutput.writeToTable(TableOutput.java:304) ... 3 more
经过在网上查询,\xF0\x9F开头的确实是UTF8字符集范围;UTF8长度是2-4个字节,我们在Mysql常用的是2-3个字节长,但这个抛出来的错误显示是4个字节,所以就错在这了(用java写代码也会报同样错误,原因是jdbc在做数据插入前会严格检查字段的类型、长度,一但不符就会抛出异常;php在这方面稍微自作聪明点,会把多出来的字节截掉,但对数据本身就是丢掉了信息,不适合做数据ETL方面的工作)。
又经过网上查询,有说这种字符属于emoji表情符,关于emoji是什么,点这里有科普 http://baike.baidu.com/view/2631589.htm
找到问题就好办了,将f_char_name字段的字符集改为utf8mb4,在Kettle的数据库连接高级设置中,设置当前会话字符集为utf8mb4,问题解决。
经过这次问题,以后有些字段有必要考虑设置成utf8mb4字符集来支持更广阔的字符内容,缺点显而易见,就是多占地儿了。
是否采用,视具体情况而定吧。
补充:
在web应用中,可在数据源配置中增加配置项来实现
<property name="connectionInitSqls" value="set names utf8mb4;"/>
推荐阅读
-
mysql修改数据库默认路径无法启动问题的解决
-
Navicat Premium 解决无法连接远程mysql数据库问题
-
简析mysql字符集导致恢复数据库报错问题
-
Mysql数据库无法启动问题的解决方案
-
navicate 远程无法链接linux上mysql数据库问题
-
Mysql匿名登录无法创建数据库问题解决方案
-
解决win10安装MySQL数据库出现服务无法启动的问题
-
解决python无法安装mysql数据库问题
-
mysql数据库中字符集乱码问题原因及解决
-
针对mysql数据库无法在表中插入中文字符的解决方案(彻底解决:java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x92\x94‘ )