kowala's home

kowala's home
這裡是我的學習筆記,陸續增加中。
http://kowala21.blogspot.com

2011-06-14

C++ & MySQL 中文問題及解決辦法

MySQL 中文問題及解決辦法

這個問題由來已久了,之前用JAVA已經解決了,但是現在是用C++,又要重新痛苦一次。

問題說明:
要想解決中文問題,須先了解問題的原因,才能想辦法解決。MySQL本身預設的語系是 latin1,有時我們安裝MySQL時會指定 UTF8,而 Connector 的語系是 latin1,然後應用程式或網頁是 big5,如此一來,怎麼弄都弄不來的。

        MySQL(utf8)<-Connector(latin1)->API(big5)

好了,問題知道了,該如何解決?這要分三個部份去做,上述三層的語系都要一致,就不會出現亂碼了。
如下所示:

        MySQL(big5)<-Connector(big5)->API(big5)

或是

        MySQL(utf8)<-Connector(utf8)->API(UTF-8)

注意:UTF-8 在 MySQL 是寫做 utf8,在網頁中是寫做 UTF-8,不可弄錯。

上述是網頁亂碼的處理原則,然而C++中該如何處理呢?目前我還在努力中,如果各位大大已經解決的,還請告訴小弟我,我會很感激的。^^

我目前處理的進度,構想是全部採用UTF-8,這樣就可以簡繁體並列,不會衝突。

1.在 MySQL 的設定

在 my.ini 中設定

        C:\Program Files\MySQL\MySQL Server 5.1\my.ini
        [client]
        default-character-set=utf8
        [mysql]
        default-character-set=utf8
        [mysqld]
        default-character-set=utf8

建立表格指令中加以指定語系為utf8,可以省掉這步,應為預設已經改為utf8,例如
mysql> CREATE TABLE city(bkey int not null primary key,cityname varchar(30) DEFA
ULT NULL ) DEFAULT CHARSET=utf8;

2.在Connector中也要設定為UTF8
這個我的實驗都設定失敗,感覺都沒作用。。。

        con->setClientOption("OPT_CHARSET_NAME","utf8"); 
        con->setClientOption("OPT_SET_CHARSET_NAME","utf8");

你問我為何知道要用 OPT_CHARSET_NAME 及 OPT_SET_CHARSET_NAME ? 因為我是看 connector source code 查的...

3.在API中也要設定unicode
C++中又牽扯到寬窄字元設定與轉換問題,也就是 CString  或是 wchar_t 與 std::string 轉換
的問題,假設C++中字元都處裡OK,等到要把字串寫入MySQL時,又有問題了。

ex1:直接輸入CString,這一定會錯的,此處參數為 std:string 格式。

        char *a="insert into news values(4,NOW(),'中文輸入','一直都會有亂碼');";
        CString str(a);
        stmt->executeQuery(str);

無法從 'ATL::CString'轉換為 'const std::string'
這個 stmt->executeQuery(sql); 就是 const std::string 格式,它也不是寬字元。會出現錯誤。

ex2:這次給它正確的格式,換成MySQL那邊出錯了。

        char *a="insert into news values(4,NOW(),'中文輸入','一直都會有亂碼');";
        CString str(a);
        stmt->executeQuery(a);

錯誤 SQLException:
Incorrect string value: '\xA4\xA4\xA4\xE5\xBF\xE9...' for column 'title' at row 1

這是因為我們輸入(C++)為 big5,而MySQL那邊為 utf8 所產生的錯誤,可能的問題是發生在connect,因為它只能接受 const std::string 格式的參數,我們無法把unicode透過connect傳遞給MySQL所致。
有人能幫忙解決這問題嗎?非常感謝。

connect 原始碼 下載地址 (mysql-connector-c -1.0.5src.rar)

1 則留言:

請提供您的寶貴意見 ;-)