C++連接mysql數(shù)據(jù)庫
?開發(fā)Mysql有兩種方法:
方法一:mysql.h、libmySQL.lib和libmySQL.dll的方法,此方法可以通過動態(tài)庫直接對服務(wù)器進(jìn)行修改。
要求包含#include?"mysql.h",link中要包含libmySQL.lib
MYSQL?mysql;
mysql_init?(&mysql);//初始化
mysql_real_connect(&mysql,"localhost","root",NULL,"mysql",3306,NULL,0);//連接
最后通過mysql_real_query下命令,只要你熟悉怎么通過cmd進(jìn)入mysql設(shè)置命令,把要下的命令順序用mysql_real_query使用就可以了。
CString?strSQL;
strSQL="CREATE?DATABASE?testInf";
mysql_real_query(&mysql,(char*)(LPCTSTR)strSQL,(UINT)strSQL.GetLength());
方法二:mysql?與?ODBC?動態(tài)方式
先安裝mysql?ODBC?3.51?Driver(或其他版本)
#include?”afxdb.h“
申請一個CDatabase?db;
同db函數(shù)使用。
db.OpenEx("DSN=data;UID=用戶名;PWD=密碼;DATABASE=mysql",
CDatabase::openReadOnly?|?CDatabase::noOdbcDialog);
db.ExecuteSQL("create?database?test;");//執(zhí)行創(chuàng)建database
db.ExecuteSQL("use?test");//使用test
....括號里面是你的sql命令,只有知道怎么通過cmd進(jìn)入下命令才行
最后完了要關(guān)掉db.Close();
下面是記錄
CRecordset?rs(&db);//CRecordset和CDatabases配合使用
db.ExecuteSQL("use?test");
str.Format("select?*?from?table;")
rs.Open(CRecordset::forwardOnly,str);
int?i=0;//用于記錄查到多少條
while(!rs.IsEOF())
{
???rs.MoveNext();
???i++;
}
rs.Close();
下面先使用第一種方法來連接:
新建一個名為testdb的數(shù)據(jù)庫再在其中新建一個表:name_table.然后新增數(shù)據(jù):zhb 22studentsnjupt
打開vc++6.0,工具->選項(xiàng)->目錄(選項(xiàng)卡),在其Include files添加MySQL的include路徑。如我的MySQL的include文件夾的路徑為:C:Program FilesMySQLMySQL Server 5.0include。切換下拉框,選擇Library files,添加MySQL的lib路徑。如我的為:C:Program
FilesMySQLMySQL Server 5.0lib。然后把libmysql.dll復(fù)制到debug里面
上代碼:
#include#include#include#include#include#include#pragma?comment(lib,"libmysql.lib");//連接MysQL需要的庫 using?namespace?std; int?main() { ????const?char?user[]?=?"root";?????????//username ????const?char?pswd[]?=?"123456";????//password ????const?char?host[]?=?"localhost";????//or"127.0.0.1" ????const?char?table[]?="testdb";???????//database ????unsigned?int?port?=?3306;???????????//server?port???????? ????MYSQL?myCont; ????MYSQL_RES?*result; ????MYSQL_ROW?sql_row; ????MYSQL_FIELD?*fd; ????char?column[32][32]; ????int?res; ????mysql_init(&myCont); ????if(mysql_real_connect(&myCont,host,user,pswd,table,port,NULL,0)) ????{ ????????cout<<"connect?succeed!"<<endl; ????????mysql_query(&myCont,?"SET?NAMES?GBK");?//設(shè)置編碼格式,否則在cmd下無法顯示中文 ????????res=mysql_query(&myCont,"select?*?from?name_table");//查詢 ????????if(!res) ????????{ ????????????result=mysql_store_result(&myCont);//保存查詢到的數(shù)據(jù)到result ????????????if(result) ????????????{ ????????????????int?i,j; ????????????????cout<<"number?of?result:?"<<(unsigned?long)mysql_num_rows(result)<name); ????????????????} ????????????????j=mysql_num_fields(result); ????????????????for(i=0;i<j;i++) ????????????????{ ????????????????????printf("%st",column[i]); ????????????????} ????????????????printf("n"); ????????????????while(sql_row=mysql_fetch_row(result))//獲取具體的數(shù)據(jù) ????????????????{ ????????????????????for(i=0;i<j;i++) ????????????????????{ ????????????????????????printf("%sn",sql_row[i]); ????????????????????} ????????????????????printf("n"); ????????????????} ????????????} ????????} ????????else ????????{ ????????????cout<<"query?sql?failed!"<<endl; ????????} ????} ????else ????{ ????????cout<<"connect?failed!"<<endl; ????} ????if(result!=NULL)?mysql_free_result(result);//釋放結(jié)果資源 ????mysql_close(&myCont);//斷開連接 ????return?0; }
附MySQL的API接口:
mysql_affected_rows()?返回被最新的UPDATE,?DELETE或INSERT查詢影響的行數(shù)。 ? mysql_close()?關(guān)閉一個服務(wù)器連接。 ? mysql_connect()?連接一個MySQL服務(wù)器。該函數(shù)不推薦;使用mysql_real_connect()代替。 ? mysql_change_user()?改變在一個打開的連接上的用戶和數(shù)據(jù)庫。 ? mysql_create_db()?創(chuàng)建一個數(shù)據(jù)庫。該函數(shù)不推薦;而使用SQL命令CREATE?DATABASE。 ? mysql_data_seek()?在一個查詢結(jié)果集合中搜尋一任意行。 ? mysql_debug()?用給定字符串做一個DBUG_PUSH。 ? mysql_drop_db()?拋棄一個數(shù)據(jù)庫。該函數(shù)不推薦;而使用SQL命令DROP?DATABASE。 ? mysql_dump_debug_info()?讓服務(wù)器將調(diào)試信息寫入日志文件。 ? mysql_eof()?確定是否已經(jīng)讀到一個結(jié)果集合的最后一行。這功能被反對;?mysql_errno()或mysql_error()可以相反被使用。 ? mysql_errno()?返回最近被調(diào)用的MySQL函數(shù)的出錯編號。 ? mysql_error()?返回最近被調(diào)用的MySQL函數(shù)的出錯消息。 ? mysql_escape_string()?用在SQL語句中的字符串的轉(zhuǎn)義特殊字符。 ? mysql_fetch_field()?返回下一個表字段的類型。 ? mysql_fetch_field_direct?()?返回一個表字段的類型,給出一個字段編號。 ? mysql_fetch_fields()?返回一個所有字段結(jié)構(gòu)的數(shù)組。 ? mysql_fetch_lengths()?返回當(dāng)前行中所有列的長度。 ? mysql_fetch_row()?從結(jié)果集合中取得下一行。 ? mysql_field_seek()?把列光標(biāo)放在一個指定的列上。 ? mysql_field_count()?返回最近查詢的結(jié)果列的數(shù)量。 ? mysql_field_tell()?返回用于最后一個mysql_fetch_field()的字段光標(biāo)的位置。 ? mysql_free_result()?釋放一個結(jié)果集合使用的內(nèi)存。 ? mysql_get_client_info()?返回客戶版本信息。 ? mysql_get_host_info()?返回一個描述連接的字符串。 ? mysql_get_proto_info()?返回連接使用的協(xié)議版本。 ? mysql_get_server_info()?返回服務(wù)器版本號。 ? mysql_info()?返回關(guān)于最近執(zhí)行得查詢的信息。 ? mysql_init()?獲得或初始化一個MYSQL結(jié)構(gòu)。 ? mysql_insert_id()?返回有前一個查詢?yōu)橐粋€AUTO_INCREMENT列生成的ID。 ? mysql_kill()?殺死一個給定的線程。 ? mysql_list_dbs()?返回匹配一個簡單的正則表達(dá)式的數(shù)據(jù)庫名。 ? mysql_list_fields()?返回匹配一個簡單的正則表達(dá)式的列名。 ? mysql_list_processes()?返回當(dāng)前服務(wù)器線程的一張表。 ? mysql_list_tables()?返回匹配一個簡單的正則表達(dá)式的表名。 ? mysql_num_fields()?返回一個結(jié)果集合重的列的數(shù)量。 ? mysql_num_rows()?返回一個結(jié)果集合中的行的數(shù)量。 ? mysql_options()?設(shè)置對mysql_connect()的連接選項(xiàng)。 ? mysql_ping()?檢查對服務(wù)器的連接是否正在工作,必要時(shí)重新連接。 ? mysql_query()?執(zhí)行指定為一個空結(jié)尾的字符串的SQL查詢。 ? mysql_real_connect()?連接一個MySQL服務(wù)器。 ? mysql_real_query()?執(zhí)行指定為帶計(jì)數(shù)的字符串的SQL查詢。 ? mysql_reload()?告訴服務(wù)器重裝授權(quán)表。 ? mysql_row_seek()?搜索在結(jié)果集合中的行,使用從mysql_row_tell()返回的值。 ? mysql_row_tell()?返回行光標(biāo)位置。 ? mysql_select_db()?連接一個數(shù)據(jù)庫。 ? mysql_shutdown()?關(guān)掉數(shù)據(jù)庫服務(wù)器。 ? mysql_stat()?返回作為字符串的服務(wù)器狀態(tài)。 ? mysql_store_result()?檢索一個完整的結(jié)果集合給客戶。 ? mysql_thread_id()?返回當(dāng)前線程的ID。 ? mysql_use_result()?初始化一個一行一行地結(jié)果集合的檢索。
?c++操作mysql :連接
c++連接mysql的主要是通過mysql的c API來實(shí)現(xiàn) 。
連接的API有兩個,下面會分別描述:
1.??mysql_connect()
(原型)ProtoType: ??MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)
描述:
該函數(shù)已過時(shí)。最好使用mysql_real_connect()取而代之。
mysql_connect()試圖建立與運(yùn)行在主機(jī)(遠(yuǎn)程主機(jī)也可以)上的MySQL數(shù)據(jù)庫引擎的連接。在能夠執(zhí)行任何其他API函數(shù)之前,必須先調(diào)用mysql_connect(),而且返回成功。但mysql_get_client_info()例外。
這些參數(shù)的意義與mysql_real_connect()的對應(yīng)參數(shù)的意義相同,差別在于連接句柄可以為NULL。在這種情況下,C API將自動為連接結(jié)構(gòu)分配內(nèi)存,并當(dāng)調(diào)用mysql_close()時(shí)釋放分配的內(nèi)存。該方法的缺點(diǎn)是,如果連接失敗,你無法檢索錯誤消息。要想從mysql_errno()或mysql_error()獲得錯誤消息,必須提供有效的MYSQL指針。
返回值: NULL表示失敗。反之成功。
2.??mysql_real_connect()
原型:
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)
描述
mysql_real_connect()嘗試與運(yùn)行在主機(jī)上的MySQL數(shù)據(jù)庫引擎建立連接。在你能夠執(zhí)行需要有效MySQL連接句柄結(jié)構(gòu)的任何其他API函數(shù)之前,mysql_real_connect()必須被調(diào)用并返回成功。
參數(shù)說明:
·???????? 第1個參數(shù)應(yīng)是已有MYSQL結(jié)構(gòu)的地址。調(diào)用mysql_real_connect()之前,?必須調(diào)用mysql_init()來初始化MYSQL結(jié)構(gòu)?。
通過mysql_options()調(diào)用,可更改多種連接選項(xiàng)。
·
host的值必須是主機(jī)名或IP地址。如果host是NULL或字符串”localhost”,連接將被視為與本地主機(jī)的連接。如果操作系統(tǒng)支持套接字(Unix)或命名管道(Windows),將使用它們而不是TCP/IP連接到服務(wù)器。
·
user參數(shù)包含用戶的MySQL登錄ID。如果user是NULL或空字符串”",用戶將被視為當(dāng)前用戶。在UNIX環(huán)境下,它是當(dāng)前的登錄名。在Windows ODBC下,必須明確指定當(dāng)前用戶名。請參見?26.1.9.2節(jié),“在Windows上配置MyODBC DSN”?。
·
passwd參數(shù)包含用戶的密碼。如果passwd是NULL,僅會對該用戶的(擁有1個空密碼字段的)用戶表中的條目進(jìn)行匹配檢查。這樣,數(shù)據(jù)庫管理員就能按特定的方式設(shè)置MySQL權(quán)限系統(tǒng),根據(jù)用戶是否擁有指定的密碼,用戶將獲得不同的權(quán)限。
注釋:?調(diào)用mysql_real_connect()之前,不要嘗試加密密碼,密碼加密將由客戶端API自動處理。
·
db是數(shù)據(jù)庫名稱。如果db為NULL,連接會將默認(rèn)的數(shù)據(jù)庫設(shè)為該值。?當(dāng)你不想連接特定數(shù)據(jù)庫時(shí),可以指定db為NULL
·
如果“port”不是0,其值將用作TCP/IP連接的端口號。注意,“host”參數(shù)決定了連接的類型。port為0的話,使用mysql的默認(rèn)tcp/ip端口3306.
·
如果unix_socket不是NULL,該字符串描述了應(yīng)使用的套接字或命名管道。注意,“host”參數(shù)決定了連接的類型。
?
·client_flag的值通常為0,但是,也能將其設(shè)置為下述標(biāo)志的組合,以允許特定功能:
?
標(biāo)志名稱
標(biāo)志描述
CLIENT_COMPRESS
使用壓縮協(xié)議。
CLIENT_FOUND_ROWS
返回發(fā)現(xiàn)的行數(shù)(匹配的),而不是受影響的行數(shù)。
CLIENT_IGNORE_SPACE
允許在函數(shù)名后使用空格。使所有的函數(shù)名成為保留字。
CLIENT_INTERACTIVE
關(guān)閉連接之前,允許interactive_timeout(取代了wait_timeout)秒的不活動時(shí)間??蛻舳说臅抴ait_timeout變量被設(shè)為會話interactive_timeout變量的值。
CLIENT_LOCAL_FILES
允許LOAD DATA LOCAL處理功能。
CLIENT_MULTI_STATEMENTS
通知服務(wù)器,客戶端可能在單個字符串內(nèi)發(fā)送多條語句(由‘;’隔開)。如果未設(shè)置該標(biāo)志,將禁止多語句執(zhí)行。
CLIENT_MULTI_RESULTS
通知服務(wù)器,客戶端能夠處理來自多語句執(zhí)行或存儲程序的多個結(jié)果集。如果設(shè)置了CLIENT_MULTI_STATEMENTS,將自動設(shè)置它。
CLIENT_NO_SCHEMA
禁止?db_name.tbl_name.col_name?語法。它用于ODBC。如果使用了該語法,它會使分析程序生成錯誤,在捕獲某些ODBC程序中的缺陷時(shí),它很有用。
CLIENT_ODBC
客戶端是ODBC客戶端。它將?mysqld?變得更為ODBC友好。
CLIENT_SSL
使用SSL(加密協(xié)議)。該選項(xiàng)不應(yīng)由應(yīng)用程序設(shè)置,它是在客戶端庫內(nèi)部設(shè)置的。
示例代碼:
?
1
2
3
4
5
6
mysql_init?(?&?mysql?)?;
?
if?(?!?mysql_real_connect?(?&?mysql?,?"host"?,?"user"?,?"passwd"?,?"database"?,?0?,?NULL?,0?)?)
{?//判斷連接是否失敗。
?????printf?(?"Failed to connect to database: Error: %s/n"?,????mysql_error?(?&?mysql?)?)?;
}
?
連接成功后,你就可以執(zhí)行其他操作了。
mysql_connect和mysql_real_connect的區(qū)別: 1. mysql_connect不需要調(diào)用mysql_init來初始化連接句柄.但是mysql_real_connect需要。 2. mysql_connect只能指定host,user,password, database四個參數(shù),無法指定特定端口,使用命名管道。只能使用默認(rèn)的TCP/IP連接。默認(rèn)端口只能是3306 3. mysql_connect在實(shí)現(xiàn)里調(diào)用了mysql_real_connect.是對其的封裝。 我們可以從庫的實(shí)現(xiàn)文件libmysql.c看到mysql_connect()函數(shù)的實(shí)現(xiàn): MYSQL * STDCALL mysql_connect(MYSQL *mysql,const char *host,?const char *user, const char *passwd) { ??MYSQL *res; ??mysql=mysql_init(mysql); /* Make it thread safe */ ??{ ?? ?DBUG_ENTER(“mysql_connect”); ? ?if (!(res = mysql_real_connect(mysql, host, user, passwd, null, 0, null, 0))) ?? { ?? ? ?if (mysql->free_me) my_free((gptr) mysql,MYF(0)); ?? ?} ?? ?DBUG_RETURN(res); ??} } mysql_real_connect的實(shí)現(xiàn)就很長很復(fù)雜了。在此不貼出,有需要的同學(xué)可通過向我索取。 通過這兩個函數(shù),大家想必對mysql的連接都更多的了解了。在實(shí)際運(yùn)用過程中,這兩個函數(shù)已經(jīng)夠用了。還有需要用到的是 mysql_options來通過更改連接選項(xiàng)。 備注: 本文函數(shù)說明來自mysql5.1官方文檔。 所需資料均來自mysql。 c++操作mysql :查詢
講完了連接,接著就講查詢了。
mysql的執(zhí)行和查詢都是使用一下2個接口:
1. mysql_query(MYSQL* mysql, const char* sql);
2.?int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);
一下就分別描述這兩個函數(shù):
1.??mysql_query()
int mysql_query(MYSQL *mysql, const char *query)
?
描述
執(zhí)行由“Null終結(jié)的字符串”查詢指向的SQL查詢。正常情況下,字符串必須包含1條SQL語句,?而且不應(yīng)為語句添加終結(jié)分號(‘;’)或“/g”。如果允許多語句執(zhí)行?,字符串可包含多條由分號隔開的語句。但是連接的時(shí)候必須指定CLIENT_MULTI_STATEMENTS選項(xiàng)。
mysql_query()不能用于包含二進(jìn)制數(shù)據(jù)的查詢,應(yīng)使用mysql_real_query()取而代之(二進(jìn)制數(shù)據(jù)可能包含字符‘/0’,mysql_query()會將該字符解釋為查詢字符串結(jié)束)。
如果希望了解查詢是否應(yīng)返回結(jié)果集,可使用mysql_field_count()進(jìn)行檢查。請參見25.2.3.22節(jié),“mysql_field_count()”?。
返回值
如果查詢成功,返回0。如果出現(xiàn)錯誤,返回非0值。
2.??mysql_real_query()
int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)
描述
執(zhí)行由“query”指向的SQL查詢,它應(yīng)是字符串長度字節(jié)“l(fā)ong”。正常情況下,字符串必須包含1條SQL語句,?而且不應(yīng)為語句添加終結(jié)分號(‘;’)或“/g”?。如果允許多語句執(zhí)行,字符串可包含由分號隔開的多條語句。但是連接的時(shí)候必須指定CLIENT_MULTI_STATEMENTS選項(xiàng)。
對于包含二進(jìn)制數(shù)據(jù)的查詢,必須使用mysql_real_query()而不是mysql_query(),這是因?yàn)椋M(jìn)制數(shù)據(jù)可能會包含‘/0’字符。此外,mysql_real_query()比mysql_query()快,這是因?yàn)樗粫诓樵冏址险{(diào)用strlen()。
如果希望知道查詢是否應(yīng)返回結(jié)果集,可使用mysql_field_count()進(jìn)行檢查?25.2.3.22節(jié),“mysql_field_count()”?。
返回值
如果查詢成功,返回0。如果出現(xiàn)錯誤,返回非0值。
如果失敗,可使用mysql_error(MYSQL* mysql)看看錯誤信息。
使用mysql_query和mysql_real_query可以執(zhí)行任何的mysql語句。不需要在語句末尾加上分號!
對于沒有像select一樣的查詢,需要接著調(diào)用mysql_store_result或者mysql_use_result來保存結(jié)果集。
對于insert或者delete,create語句,不返回結(jié)果集的,判斷返回值看看是否執(zhí)行成功,然后用mysql_affected_rows函數(shù)來
查詢被影響的行數(shù)。用mysql_error(MYSQL* mysql)來看錯誤信息
c++操作mysql :查詢結(jié)果集
用mysql進(jìn)行數(shù)據(jù)查詢的時(shí)候,mysql會返回一個結(jié)果集給我們。接著我們需要調(diào)用mysql的api,從這個結(jié)果集中取得我們要的數(shù)據(jù)。
取完數(shù)據(jù)之后,需要釋放這個結(jié)果集。
mysql的結(jié)果集其實(shí)就是一個MYSQL_RES結(jié)構(gòu),其定義如下:
typedef struct??st_mysql_res??{
my_ulonglong row_count; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 結(jié)果集的行數(shù)
unsigned int field_count, current_field; ?? ? ? ? ??// 結(jié)果集的列數(shù),當(dāng)前列
MYSQL_FIELD?*fields; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??// 結(jié)果集的列信息
MYSQL_DATA?*data; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??// 結(jié)果集的數(shù)據(jù)
MYSQL_ROWS?*data_cursor; ?? ? ? ? ? ? ? ? ? ? ??// 結(jié)果集的光標(biāo)
MEM_ROOT?field_alloc; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 內(nèi)存結(jié)構(gòu)
MYSQL_ROW?row; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 非緩沖的時(shí)候用到
MYSQL_ROW?current_row; ? ? ? ? ? ? ? ? ? ? ? ? ? //mysql_store_result時(shí)會用到。當(dāng)前行
unsigned long *lengths; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //每列的長度
MYSQL?*handle; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// mysql_use_result會用。
my_bool eof; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//是否為行尾
} MYSQL_RES;
typedef char **?MYSQL_ROW?; /* 返回的每一行的值,全部用字符串來表示*/ typedef struct st_mysql_rows { ??struct st_mysql_rows *next; /* list of rows */ ??MYSQL_ROW data; }??MYSQL_ROWS?; ? ? ? ?//mysql的數(shù)據(jù)的鏈表節(jié)點(diǎn)??梢妋ysql的結(jié)果集是鏈表結(jié)構(gòu) typedef struct st_mysql_data { ??my_ulonglong rows; ??unsigned int fields; ??MYSQL_ROWS *data; ??MEM_ROOT alloc; }??MYSQL_DATA?; // 數(shù)據(jù)集的結(jié)構(gòu) typedef struct st_mysql_field { ??char *name; /* Name of column */ ??char *table; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??/* Table of column if column was a field */ ??char *def; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* Default value (set by mysql_list_fields) */ ??enum enum_field_types type; ?? ? ? ? ? ? ? /* Type of field. Se mysql_com.h for types */ ??unsigned int length; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* Width of column */ ??unsigned int max_length; ?? ? ? ? ? ? ? ? ? ? ?/* Max width of selected set */ ??unsigned int flags; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* Div flags */ ??unsigned int decimals; ?? ? ? ? ? ? ? ? ? ? ? ? ??/* Number of decimals in field */ }??MYSQL_FIELD?; ?//列信息的結(jié)構(gòu)
typedef struct st_used_mem { /* struct for once_alloc */
struct st_used_mem *next; /* Next block in use */
unsigned int left; /* memory left in block ?*/
unsigned int size; /* Size of block */
}??USED_MEM?; //內(nèi)存結(jié)構(gòu)
typedef struct st_mem_root {
<p style="font-size:16px;font-family:'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', '微軟雅黑', sans-serif;color:rgb(51,51,51);line-height:27px;back