前言
最近在公司編寫存儲過程,碰到了一個問題,排查了很久,才解決,現記錄一下,給各位踩踩坑。
問題
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
4. 再次檢視編碼:
再次運作sql語句,cluster_value值即正常
原因猜想
存儲過程中定義參數時,無法定義其字元集,是以調用存儲過程的時候,會預設讀取全局變量character_set_server,而且還是隻讀取mysqld啟動時該全局變量的值作為存儲過程中預設的傳輸字元集。是以,如果資料表/字段使用系統預設的字元集(比如latin1)的話,調用存儲過程更新一些非英文的字元串字段時,就不會發生問題;但是,如果資料表/字段的字元集不是系統預設的字元集(比如預設是latin1,資料表使用的是utf8),就會出現問題。
這個問題看起來很小,但定位的時候老折磨了