记mysql存储过程给变量赋值的坑

前言

最近在公司编写存储过程,碰到了一个问题,排查了很久,才解决,现记录一下,给各位踩踩坑。

问题

SET cluster_value = CONCAT('{"Desc":"这是一个中文字符串"',NOW(), '","OtherStatus":0,"OneStatus":0}');
SELECT cluster_value;

打印 cluster_value ,值为null

记mysql存储过程给变量赋值的坑

寻找原因,开始认为是以下几个方面:

  1. cluster_value变量声明的大小不够
  2. 给cluster_value赋值的sql语句格式错误
  3. cluster_value被其他sql语句影响

三点都验证了一遍,发现仍然没有问题,然后就想是不是字符串里的内容有问题,于是继续验证,最终发现是只要含有中文字符就有问题,修改成英文就正常。

瞬间,局势就爽朗起来了呀!

于是上到mysql所在的服务器,准备大刀阔斧的干

解决方法

1. 使用 show variables like 'character%' 查看数据库编码:

记mysql存储过程给变量赋值的坑

发现 character _set_server 的字符集是 latin1,需要将其换成 utf8mb4

2. 进入my.cnf 文件(位置一般在mysql安装的位置)中,在【mysqld】里输入character-set-server=utf8mb4

3. 重启mysql(重启链接:https://blog.csdn.net/cx136295988/article/details/76690722)

4. 再次查看编码:

记mysql存储过程给变量赋值的坑

再次运行sql语句,cluster_value值即正常

原因猜想

存储过程中定义参数时,无法定义其字符集,因此调用存储过程的时候,会默认读取全局变量character_set_server,而且还是只读取mysqld启动时该全局变量的值作为存储过程中默认的传输字符集。因此,如果数据表/字段使用系统默认的字符集(比如latin1)的话,调用存储过程更新一些非英文的字符串字段时,就不会发生问题;但是,如果数据表/字段的字符集不是系统默认的字符集(比如默认是latin1,数据表使用的是utf8),就会出现问题。

这个问题看起来很小,但定位的时候老折磨了

上一篇:LNMP网站服务器连接redis集群配置概要


下一篇:vue动态组件