mysql: Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '= 的解決


昨天把mysql里所有table的varchar字段的字符集,批量換成了utf8mb4/utf8mb4_unicode_ci ,以便能保存一些emoji火星文 , 結果有一個sql語句執行時,報錯如下:

Illegalmixofcollations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT)foroperation '=

觀察了一下,這個sql使用了一個自定義的function,這個函數的入口參數為varchar,類似如下:

CREATE FUNCTION `f_xxx`(
  p_ref_type     VARCHAR(50) ,
  ...
)

問題就在這里,把p_ref_type的參數類型改成:

CREATE FUNCTION `f_xxx`(
  p_ref_type     VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
  ...
)

就ok了。

 

當然,如果不想改function,還有一種一勞永逸的解決辦法:(需要停機)

出錯信息的意思是 utf8-unicode-cli與utf-general-cli 不能混用,可以用

show create function f_xxx\G 查看下結構,重點觀察下最后幾行:

...

  END
character_set_client: utf8mb4
collation_connection: utf8mb4_unicode_ci
  Database Collation: utf8_general_ci
1 row in set (0.00 sec)

這里可以看出,collation_connnection 與 Database Collation所用的字符集不一致,要想辦法弄成一致,可以再用:

SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';

查看mysql的相關系統變量:

| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8mb4_general_ci |
| collation_server | utf8mb4_general_ci |

大概輸出是這樣的,注意最后3行,確認mysql實例的編碼后,可以調整database的編碼:

ALTER DATABASE `數據庫名` character set utf8mb4 COLLATE utf8mb4_general_ci ;

考慮到,有些表或字段在創建時,可能也指定了其它編碼,可以用:

./mysqldump -u用戶名 -p -d --add-drop-table 數據庫名 > 導出的文件名

注:為防止操作期間有人操作數據庫,最好將所有應用暫時停機,保證操作期間db沒人向其寫入數據 。

導出表結構的sql,然后用文本編碼工具,批量把指定字符集的字符串給批量清空,即:清除所有指定字符集的DDL語句,全部默認用database本身的字符集

接下來用

./mysqldump -u用戶名 -p -t 數據庫名 > 導出的文件名 

導出所有數據

最后,干掉所有table,然后mysql命令行下

source 修改好以后的數據庫表結構.sql

source 數據.sql

將所有表重建,然后導入數據,進行恢復,最終目標是將整個db,包括所有表及字段的字符集大換血了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM