记mysql存储过程给变量赋值的坑
前言
最近在公司编写存储过程,碰到了一个问题,排查了很久,才解决,现记录一下,给各位踩踩坑。
问题
SET cluster_value = CONCAT('{"Desc":"这是一个中文字符串"',NOW(), '","OtherStatus":0,"OneStatus":0}'); SELECT cluster_value;
打印 cluster_value ,值为null
寻找原因,开始认为是以下几个方面:
- cluster_value变量声明的大小不够
- 给cluster_value赋值的sql语句格式错误
- cluster_value被其他sql语句影响
三点都验证了一遍,发现仍然没有问题,然后就想是不是字符串里的内容有问题,于是继续验证,最终发现是只要含有中文字符就有问题,修改成英文就正常。
瞬间,局势就爽朗起来了呀!
于是上到mysql所在的服务器,准备大刀阔斧的干
解决方法
1. 使用 show variables like 'character%' 查看数据库编码:
发现 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. 再次查看编码:
再次运行sql语句,cluster_value值即正常
原因猜想
存储过程中定义参数时,无法定义其字符集,因此调用存储过程的时候,会默认读取全局变量character_set_server,而且还是只读取mysqld启动时该全局变量的值作为存储过程中默认的传输字符集。因此,如果数据表/字段使用系统默认的字符集(比如latin1)的话,调用存储过程更新一些非英文的字符串字段时,就不会发生问题;但是,如果数据表/字段的字符集不是系统默认的字符集(比如默认是latin1,数据表使用的是utf8),就会出现问题。
这个问题看起来很小,但定位的时候老折磨了