首页 > 技术文章 > 关于mysql存储过程存储4字节emoj的'\xF0\x9F\x98\x82' for column ``.``.`p_topicname`问题的解决办法

marshwinter 2020-09-28 14:42 原文

一、问题背景

背景很简单,要存4字节的表情符号,mysql表的相关字段的字符集需要修改成utf8mb4,这个没啥好说的,网上一大堆的类似的解决方法,问题是项目里面使用了存储过程,在利用java调用存储过程的时候,老报错,整个人直接就傻了,还好利用google找到了问题的解决办法,贴一下报错内容,其中p_topicname是存储过程的输入参数

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect string value: '\xF0\x9F\x98\x82' for column ``.``.`p_topicname` at row 1
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3885)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2530)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1907)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1199)
    at com.mysql.jdbc.CallableStatement.execute(CallableStatement.java:870)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
    at com.zaxxer.hikari.pool.HikariProxyCallableStatement.execute(HikariProxyCallableStatement.java)

二、解决思路

参考这篇https://www.codenong.com/44591895/(应该是stackoverflow之类网站上的机翻吧),防止连接失效,讲一下大概解决思路,首先利用 SHOW PROCEDURE STATUS where name LIKE 'p_addzhihuquestion';这个命令可以看到存储过程的相关状态,里面是有字符设置的相关状态,这个就比较夸张了,至于character_set_client的具体含义,百度即可,前者指客户端的连接字符集

image

那最后问题解决办法就很简单了,只要在相关的字符集连接环境下重新建立存储过程即可,

  1 DROP PROCEDURE p_addzhihuquestion
  2 SET NAMES utf8mb4;
  3 delimiter $$
  4 
  5 CREATE DEFINER=`ilinkie_test`@`%` PROCEDURE `p_addzhihuquestion`(IN `p_questionuuid` varchar(32),IN `p_useruuid` varchar(32),IN `p_title` varchar(255),IN `p_content` varchar(1000))
  6 BEGIN
  7   #Routine body goes here...
  8 END$$
  9 
 10 delimiter;

最后使用命令重新查看一下

image

character_set_client变成utf8mb4了,现在可以重新愉快玩耍了

推荐阅读