前言
最近在公司編寫存儲過程,碰到了一個問題,排查了很久,才解決,現記錄一下,給各位踩踩坑。
問題
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),就會出現問題。
這個問題看起來很小,但定位的時候老折磨了