kowala's home

kowala's home
這裡是我的學習筆記,陸續增加中。
http://kowala21.blogspot.com
顯示具有 MySQL 標籤的文章。 顯示所有文章
顯示具有 MySQL 標籤的文章。 顯示所有文章

2011-06-14

C++ & MySQL 中文問題III


為了解決 MySQL 使用UTF-8 的中文問題,今天尋找到另一個連接器 mysql++
下載原始碼,編譯,準備測試。。。
這個比較麻煩,要自己編譯,還要引用到 MySQL 的 .h 檔,這意味著您必須下載 MySQL Server 的 .h
來,開始玩吧!

首先,請先下載 mysql++-3.1.0.tar.gz 與 mysql-noinstall-5.1.51-win32.zip
在這 http://tangentsoft.net/mysql++ 下載 mysql++
分別解壓縮兩個檔案
先執行 mysql++ 專案

...\Desktop\mysql++-3.1.0\vc2008\mysql++.sln

後,在 mysql-noinstall-5.1.51-win32\include 中,找到下列檔案

mysql-noinstall-5.1.51-win32\include
mysql_version.h
mysql.h
mysql_com.h
mysql_time.h
my_list.h
typelib.h
my_alloc.h

mysql-noinstall-5.1.51-win32\lib\opt
libmysql.lib (這個需再專案屬性中指定所在路徑)

這些要跟您所用的MySQL版本配合,解壓縮到 mysql++-3.1.0\lib 之中,然後把 *.cpp 的符號

#include <mysql_version.h>

改成 

#include "mysql_version.h"

這樣就會找現行目錄了



編譯前先改成 Release,並指定專案屬性中 libmysql.lib 所在路徑
編譯完成的元件,會在目錄中

mysql++-3.1.0\vc2008\Release



我已經編譯好了,適用 mysql-5.1.51-win32

文件下載地址 (mysql 5.1.51.rar)

其他 MySQL 版本,請自行編譯。

改天找時間測試 UTF-8 看看。

這有一些使用的參考文章,是 mysql++ 內附的範例,剛剛在 google 找使用範例,
找了半天,才找到一兩個,突然想到去 mysql++ 裏頭找,果然有
節錄如下

/***********************************************************************
 simple1.cpp - Example showing the simplest way to get data from a MySQL
    table with MySQL++.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2009 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS.txt file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "cmdline.h"
#include "printdata.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;

int
main(int argc, char *argv[])
{
    // Get database access parameters from command line
    mysqlpp::examples::CommandLine cmdline(argc, argv);
    if (!cmdline) {
        return 1;
    }

    // Connect to the sample database.
    mysqlpp::Connection conn(false);
    if (conn.connect(mysqlpp::examples::db_name, cmdline.server(),
            cmdline.user(), cmdline.pass())) {
        // Retrieve a subset of the sample stock table set up by resetdb
        // and display it.
        mysqlpp::Query query = conn.query("select item from stock");
        if (mysqlpp::StoreQueryResult res = query.store()) {
            cout << "We have:" << endl;
            mysqlpp::StoreQueryResult::const_iterator it;
            for (it = res.begin(); it != res.end(); ++it) {
                mysqlpp::Row row = *it;
                cout << '\t' << row[0] << endl;
            }
        }
        else {
            cerr << "Failed to get item list: " << query.error() << endl;
            return 1;
        }

        return 0;
    }
    else {
        cerr << "DB connection failed: " << conn.error() << endl;
        return 1;
    }
}

/***********************************************************************
 simple2.cpp - Retrieves the entire contents of the sample stock table
    using a "store" query, and prints it out.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2009 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS.txt file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "cmdline.h"
#include "printdata.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;

int
main(int argc, char *argv[])
{
    // Get database access parameters from command line
    mysqlpp::examples::CommandLine cmdline(argc, argv);
    if (!cmdline) {
        return 1;
    }

    // Connect to the sample database.
    mysqlpp::Connection conn(false);
    if (conn.connect(mysqlpp::examples::db_name, cmdline.server(),
            cmdline.user(), cmdline.pass())) {
        // Retrieve the sample stock table set up by resetdb
        mysqlpp::Query query = conn.query("select * from stock");
        mysqlpp::StoreQueryResult res = query.store();

        // Display results
        if (res) {
            // Display header
            cout.setf(ios::left);
            cout << setw(31) << "Item" <<
                    setw(10) << "Num" <<
                    setw(10) << "Weight" <<
                    setw(10) << "Price" <<
                    "Date" << endl << endl;

            // Get each row in result set, and print its contents
            for (size_t i = 0; i < res.num_rows(); ++i) {
                cout << setw(30) << res[i]["item"] << ' ' <<
                        setw(9) << res[i]["num"] << ' ' <<
                        setw(9) << res[i]["weight"] << ' ' <<
                        setw(9) << res[i]["price"] << ' ' <<
                        setw(9) << res[i]["sdate"] <<
                        endl;
            }
        }
        else {
            cerr << "Failed to get stock table: " << query.error() << endl;
            return 1;
        }

        return 0;
    }
    else {
        cerr << "DB connection failed: " << conn.error() << endl;
        return 1;
    }
}


/***********************************************************************
 simple3.cpp - Example showing how to use the 'use' method of retrieving
    a table, as opposed to the more common 'store' method illustrated
    by the simple2 example.

 Copyright (c) 2005-2009 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "cmdline.h"
#include "printdata.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;

int
main(int argc, char *argv[])
{
    // Get database access parameters from command line
    mysqlpp::examples::CommandLine cmdline(argc, argv);
    if (!cmdline) {
        return 1;
    }

    // Connect to the sample database.
    mysqlpp::Connection conn(false);
    if (conn.connect(mysqlpp::examples::db_name, cmdline.server(),
            cmdline.user(), cmdline.pass())) {
        // Ask for all rows from the sample stock table and display
        // them.  Unlike simple2 example, we retreive each row one at
        // a time instead of storing the entire result set in memory
        // and then iterating over it.
        mysqlpp::Query query = conn.query("select * from stock");
        if (mysqlpp::UseQueryResult res = query.use()) {
            // Display header
            cout.setf(ios::left);
            cout << setw(31) << "Item" <<
                    setw(10) << "Num" <<
                    setw(10) << "Weight" <<
                    setw(10) << "Price" <<
                    "Date" << endl << endl;

            // Get each row in result set, and print its contents
            while (mysqlpp::Row row = res.fetch_row()) {
                cout << setw(30) << row["item"] << ' ' <<
                        setw(9) << row["num"] << ' ' <<
                        setw(9) << row["weight"] << ' ' <<
                        setw(9) << row["price"] << ' ' <<
                        setw(9) << row["sdate"] <<
                        endl;
            }

            // Check for error: can't distinguish "end of results" and
            // error cases in return from fetch_row() otherwise.
            if (conn.errnum()) {
                cerr << "Error received in fetching a row: " <<
                        conn.error() << endl;
                return 1;
            }
            return 0;
        }
        else {
            cerr << "Failed to get stock item: " << query.error() << endl;
            return 1;
        }
    }
    else {
        cerr << "DB connection failed: " << conn.error() << endl;
        return 1;
    }
}

C++ & MySQL 中文問題II

繼上一篇到現在,還是沒有解決在 C++ 使用 UTF-8 連線 MySQL 的問題,現在確定 connector 105 是不支援 UTF-8 的,此外 connector 106 也是不支援的。請參考官網的問答。 
Re: How can I use unicode using connector/C++?

No explicit unicode support yet. 1.0.6 (September 2009) will introduce a sql::String abstraction class as a first step toward multi-byte character sets. However, the step towards ICU or similar is not on the roadmap for the next months. 

那現在只能使用 big5 來連線及儲存資料了,也就是

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

這種方式來連線,剛剛看到大陸的朋友已經解決這個問題,他使用gb2312,節錄文章如下(用紅色表示),這應該可以修改使用,繁體中文在 MySQL 中也是叫做 big5 ,但這樣就不能簡繁並列了,唯一的遺憾。
註:下面的#include xxxx符號秀出不來,我用全形符號代替

用MySQL Connector C++访问MySql数据库,中文UTF-8乱码的解决
作者:淡月清风 日期:2010-07-11

// MySqlTest.cpp : 定义控制台应用程序的入口点。
//
 
#include <iostream>
using namespace std;
 
//MySQL Connector C++ 1.0.5,接口跟Oracle的OCCI长的很像(跟JDBC也像),Oracle-MySql官方网站可下载
//D:\Program Files\MySQL\MySQL Connector C++ 1.0.5\include
//D:\Program Files\MySQL\MySQL Connector C++ 1.0.5\lib\opt
 
#include <mysql_connection.h
#include <cppconn/statement.h
#include <cppconn/exception.h
using namespace sql;
using namespace sql::mysql;
 
#pragma comment(lib,"mysqlcppconn.lib")
 
int main(int argc, char* argv[])
{
    try
    {
        //数据库连接
        MySQL_Connection MySqlConn("localhost","root","006355");
       
        //选择数据库(模式)
        MySqlConn.setSchema("test");
 
        Statement *pStatement = MySqlConn.createStatement();
 
        //在Mysql数据库中,我设置的编码是GB2312,但是这里读出的仍是UTF-8编码的字符
        //所以需这句来解决乱码问题
 
        //执行无记录集返回的语句
        pStatement->execute("set names gb2312");
 
        //执行有记录集返回的语句
        //注意反引号 "`",呵呵
        ResultSet* pRs=pStatement->executeQuery("Select * from `Users`");
 
        while (pRs->next())
        {
            cout< getInt("id")<
           
 
            string sChineseText=pRs->getString(2);
            cout< <<":";
           
            //输出汉字的编码
            //D5 C5 C8 FD               张三  ANSI/OEM936:GBK/GB2312
            //E5 BC A0 E4 B8 89    张三  UTF8
            for (size_t i=0;i
            {
                printf("%02X ",(unsigned char)sChineseText[i]);
            }
            cout<
 
            cout< getString("password")< <
        }
       
        pRs->close();
        pStatement->close();
        MySqlConn.close();
    }
    catch (SQLException& ex)
    {
        cout<<"Error:"< <
    }
 
    return 0;
}