解決MySQL中文字符集亂碼

1. 問題現象

最近出現程序在運行一段時間之後,新入到MySQL中的數據出現中文亂碼,每次重啓程序就會好,然後過段時間又會出現問題?

2. 解決方案

經過排查懷疑是因爲在程序入庫程序執行中途,出現過與MySQL自動重連的操作,在自動重連以後所有配置都會使用默認的,所以字符集也相應會變成默認,而不再是剛開始建立連接時使用的UTF-8。
在引擎中當前與MySQL建立連接時用到的主要API函數如下:

 //1. 設置連接參數
int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)

//2. 設置字符集
ret = mysql_real_query(mysql, "SET NAMES UTF8;",    (unsigned long) strlen ("SET NAMES UTF8;"));  

//3. 與MySQL建立連接
MYSQL *mysql_real_connect (MYSQL *mysql,
    const char *host,
    const char *user, 
    const char *passwd, 
    const char *db, 
    unsigned int port,
    const char *unix_socket,
    unsigned long client_flag);

以上的第2步中使用命令行的方式設置字符集編碼後,如果中途出現自動重連的會恢復到默認字符集。所以修改爲如下API設置:

//2. 設置連接字符集
int mysql_set_character_set(MYSQL *mysql, char *csname)

3. 幾種設置字符集的方式和對比

mysql在C/C++中調用api設置連接mysql的編碼方式有以下幾種方法:1. mysqli_set_charset調用示例:

ret = mysql_set_character_set(mysql, "utf8");  

說明:
推薦使用的設置方法,與mysql的連接斷開自動重連後仍能保持設置的編碼格式,並且影響mysql_real_escape_string函數功能,使mysql_real_escape_string函數使用設置的編碼格式轉義字符串。
但該函數在mysql5.0.5版本以後才支持,故版本太低者…。2. 執行sql語句:SET NAMES
調用示例:

ret = mysql_real_query(mysql, "SET NAMES UTF8;",    (unsigned long) strlen ("SET NAMES UTF8;"));  

說明:
使用sql語句執行,只能影響當前與數據庫的連接,斷開自動重連後編碼格式會重置爲默認的配置。3. 設置MYSQL_SET_CHARSET_NAME屬性
調用示例:

ret = mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8");  

說明:
跟mysql_set_character_set類似,斷開自動重連後仍能保持設置的編碼格式,只是不會影響到mysql_real_escape_string函數。
並且在mysql5.0.5版本都可以使用,低版本可以使用該方法代替。
需要特別說明的是只有在調用mysql_real_connect連接數據庫之前修改該屬性纔會生效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章