?開發(fā)Mysql有兩種方法:
方法一:mysql.h、libmySQL.lib和libmySQL.dll的方法,此方法可以通過動態(tài)庫直接對服務器進行修改。
要求包含#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進入mysql設置命令,把要下的命令順序用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函數使用。
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進入下命令才行
最后完了要關掉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的數據庫再在其中新建一個表:name_table.然后新增數據:zhb 22studentsnjupt
打開vc++6.0,工具->選項->目錄(選項卡),在其Include files添加MySQL的include路徑。如我的MySQL的include文件夾的路徑為:C:Program FilesMySQLMySQL Server 5.0include。切換下拉框,選擇Library files,添加MySQL的lib路徑。如我的為:C:Program
FilesMySQLMySQL Server 5.0lib。然后把libmysql.dll復制到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");?//設置編碼格式,否則在cmd下無法顯示中文 ????????res=mysql_query(&myCont,"select?*?from?name_table");//查詢 ????????if(!res) ????????{ ????????????result=mysql_store_result(&myCont);//保存查詢到的數據到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))//獲取具體的數據 ????????????????{ ????????????????????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);//釋放結果資源 ????mysql_close(&myCont);//斷開連接 ????return?0; }
附MySQL的API接口:
mysql_affected_rows()?返回被最新的UPDATE,?DELETE或INSERT查詢影響的行數。 ? mysql_close()?關閉一個服務器連接。 ? mysql_connect()?連接一個MySQL服務器。該函數不推薦;使用mysql_real_connect()代替。 ? mysql_change_user()?改變在一個打開的連接上的用戶和數據庫。 ? mysql_create_db()?創(chuàng)建一個數據庫。該函數不推薦;而使用SQL命令CREATE?DATABASE。 ? mysql_data_seek()?在一個查詢結果集合中搜尋一任意行。 ? mysql_debug()?用給定字符串做一個DBUG_PUSH。 ? mysql_drop_db()?拋棄一個數據庫。該函數不推薦;而使用SQL命令DROP?DATABASE。 ? mysql_dump_debug_info()?讓服務器將調試信息寫入日志文件。 ? mysql_eof()?確定是否已經讀到一個結果集合的最后一行。這功能被反對;?mysql_errno()或mysql_error()可以相反被使用。 ? mysql_errno()?返回最近被調用的MySQL函數的出錯編號。 ? mysql_error()?返回最近被調用的MySQL函數的出錯消息。 ? mysql_escape_string()?用在SQL語句中的字符串的轉義特殊字符。 ? mysql_fetch_field()?返回下一個表字段的類型。 ? mysql_fetch_field_direct?()?返回一個表字段的類型,給出一個字段編號。 ? mysql_fetch_fields()?返回一個所有字段結構的數組。 ? mysql_fetch_lengths()?返回當前行中所有列的長度。 ? mysql_fetch_row()?從結果集合中取得下一行。 ? mysql_field_seek()?把列光標放在一個指定的列上。 ? mysql_field_count()?返回最近查詢的結果列的數量。 ? mysql_field_tell()?返回用于最后一個mysql_fetch_field()的字段光標的位置。 ? mysql_free_result()?釋放一個結果集合使用的內存。 ? mysql_get_client_info()?返回客戶版本信息。 ? mysql_get_host_info()?返回一個描述連接的字符串。 ? mysql_get_proto_info()?返回連接使用的協(xié)議版本。 ? mysql_get_server_info()?返回服務器版本號。 ? mysql_info()?返回關于最近執(zhí)行得查詢的信息。 ? mysql_init()?獲得或初始化一個MYSQL結構。 ? mysql_insert_id()?返回有前一個查詢?yōu)橐粋€AUTO_INCREMENT列生成的ID。 ? mysql_kill()?殺死一個給定的線程。 ? mysql_list_dbs()?返回匹配一個簡單的正則表達式的數據庫名。 ? mysql_list_fields()?返回匹配一個簡單的正則表達式的列名。 ? mysql_list_processes()?返回當前服務器線程的一張表。 ? mysql_list_tables()?返回匹配一個簡單的正則表達式的表名。 ? mysql_num_fields()?返回一個結果集合重的列的數量。 ? mysql_num_rows()?返回一個結果集合中的行的數量。 ? mysql_options()?設置對mysql_connect()的連接選項。 ? mysql_ping()?檢查對服務器的連接是否正在工作,必要時重新連接。 ? mysql_query()?執(zhí)行指定為一個空結尾的字符串的SQL查詢。 ? mysql_real_connect()?連接一個MySQL服務器。 ? mysql_real_query()?執(zhí)行指定為帶計數的字符串的SQL查詢。 ? mysql_reload()?告訴服務器重裝授權表。 ? mysql_row_seek()?搜索在結果集合中的行,使用從mysql_row_tell()返回的值。 ? mysql_row_tell()?返回行光標位置。 ? mysql_select_db()?連接一個數據庫。 ? mysql_shutdown()?關掉數據庫服務器。 ? mysql_stat()?返回作為字符串的服務器狀態(tài)。 ? mysql_store_result()?檢索一個完整的結果集合給客戶。 ? mysql_thread_id()?返回當前線程的ID。 ? mysql_use_result()?初始化一個一行一行地結果集合的檢索。
?c++操作mysql :連接
c++連接mysql的主要是通過mysql的c API來實現(xiàn) 。
連接的API有兩個,下面會分別描述:
1.??mysql_connect()
(原型)ProtoType: ??MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)
描述:
該函數已過時。最好使用mysql_real_connect()取而代之。
mysql_connect()試圖建立與運行在主機(遠程主機也可以)上的MySQL數據庫引擎的連接。在能夠執(zhí)行任何其他API函數之前,必須先調用mysql_connect(),而且返回成功。但mysql_get_client_info()例外。
這些參數的意義與mysql_real_connect()的對應參數的意義相同,差別在于連接句柄可以為NULL。在這種情況下,C API將自動為連接結構分配內存,并當調用mysql_close()時釋放分配的內存。該方法的缺點是,如果連接失敗,你無法檢索錯誤消息。要想從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()嘗試與運行在主機上的MySQL數據庫引擎建立連接。在你能夠執(zhí)行需要有效MySQL連接句柄結構的任何其他API函數之前,mysql_real_connect()必須被調用并返回成功。
參數說明:
·???????? 第1個參數應是已有MYSQL結構的地址。調用mysql_real_connect()之前,?必須調用mysql_init()來初始化MYSQL結構?。
通過mysql_options()調用,可更改多種連接選項。
·
host的值必須是主機名或IP地址。如果host是NULL或字符串”localhost”,連接將被視為與本地主機的連接。如果操作系統(tǒng)支持套接字(Unix)或命名管道(Windows),將使用它們而不是TCP/IP連接到服務器。
·
user參數包含用戶的MySQL登錄ID。如果user是NULL或空字符串”",用戶將被視為當前用戶。在UNIX環(huán)境下,它是當前的登錄名。在Windows ODBC下,必須明確指定當前用戶名。請參見?26.1.9.2節(jié),“在Windows上配置MyODBC DSN”?。
·
passwd參數包含用戶的密碼。如果passwd是NULL,僅會對該用戶的(擁有1個空密碼字段的)用戶表中的條目進行匹配檢查。這樣,數據庫管理員就能按特定的方式設置MySQL權限系統(tǒng),根據用戶是否擁有指定的密碼,用戶將獲得不同的權限。
注釋:?調用mysql_real_connect()之前,不要嘗試加密密碼,密碼加密將由客戶端API自動處理。
·
db是數據庫名稱。如果db為NULL,連接會將默認的數據庫設為該值。?當你不想連接特定數據庫時,可以指定db為NULL
·
如果“port”不是0,其值將用作TCP/IP連接的端口號。注意,“host”參數決定了連接的類型。port為0的話,使用mysql的默認tcp/ip端口3306.
·
如果unix_socket不是NULL,該字符串描述了應使用的套接字或命名管道。注意,“host”參數決定了連接的類型。
?
·client_flag的值通常為0,但是,也能將其設置為下述標志的組合,以允許特定功能:
?
標志名稱
標志描述
CLIENT_COMPRESS
使用壓縮協(xié)議。
CLIENT_FOUND_ROWS
返回發(fā)現(xiàn)的行數(匹配的),而不是受影響的行數。
CLIENT_IGNORE_SPACE
允許在函數名后使用空格。使所有的函數名成為保留字。
CLIENT_INTERACTIVE
關閉連接之前,允許interactive_timeout(取代了wait_timeout)秒的不活動時間。客戶端的會話wait_timeout變量被設為會話interactive_timeout變量的值。
CLIENT_LOCAL_FILES
允許LOAD DATA LOCAL處理功能。
CLIENT_MULTI_STATEMENTS
通知服務器,客戶端可能在單個字符串內發(fā)送多條語句(由‘;’隔開)。如果未設置該標志,將禁止多語句執(zhí)行。
CLIENT_MULTI_RESULTS
通知服務器,客戶端能夠處理來自多語句執(zhí)行或存儲程序的多個結果集。如果設置了CLIENT_MULTI_STATEMENTS,將自動設置它。
CLIENT_NO_SCHEMA
禁止?db_name.tbl_name.col_name?語法。它用于ODBC。如果使用了該語法,它會使分析程序生成錯誤,在捕獲某些ODBC程序中的缺陷時,它很有用。
CLIENT_ODBC
客戶端是ODBC客戶端。它將?mysqld?變得更為ODBC友好。
CLIENT_SSL
使用SSL(加密協(xié)議)。該選項不應由應用程序設置,它是在客戶端庫內部設置的。
示例代碼:
?
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不需要調用mysql_init來初始化連接句柄.但是mysql_real_connect需要。 2. mysql_connect只能指定host,user,password, database四個參數,無法指定特定端口,使用命名管道。只能使用默認的TCP/IP連接。默認端口只能是3306 3. mysql_connect在實現(xiàn)里調用了mysql_real_connect.是對其的封裝。 我們可以從庫的實現(xiàn)文件libmysql.c看到mysql_connect()函數的實現(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的實現(xiàn)就很長很復雜了。在此不貼出,有需要的同學可通過向我索取。 通過這兩個函數,大家想必對mysql的連接都更多的了解了。在實際運用過程中,這兩個函數已經夠用了。還有需要用到的是 mysql_options來通過更改連接選項。 備注: 本文函數說明來自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);
一下就分別描述這兩個函數:
1.??mysql_query()
int mysql_query(MYSQL *mysql, const char *query)
?
描述
執(zhí)行由“Null終結的字符串”查詢指向的SQL查詢。正常情況下,字符串必須包含1條SQL語句,?而且不應為語句添加終結分號(‘;’)或“/g”。如果允許多語句執(zhí)行?,字符串可包含多條由分號隔開的語句。但是連接的時候必須指定CLIENT_MULTI_STATEMENTS選項。
mysql_query()不能用于包含二進制數據的查詢,應使用mysql_real_query()取而代之(二進制數據可能包含字符‘/0’,mysql_query()會將該字符解釋為查詢字符串結束)。
如果希望了解查詢是否應返回結果集,可使用mysql_field_count()進行檢查。請參見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查詢,它應是字符串長度字節(jié)“l(fā)ong”。正常情況下,字符串必須包含1條SQL語句,?而且不應為語句添加終結分號(‘;’)或“/g”?。如果允許多語句執(zhí)行,字符串可包含由分號隔開的多條語句。但是連接的時候必須指定CLIENT_MULTI_STATEMENTS選項。
對于包含二進制數據的查詢,必須使用mysql_real_query()而不是mysql_query(),這是因為,二進制數據可能會包含‘/0’字符。此外,mysql_real_query()比mysql_query()快,這是因為它不會在查詢字符串上調用strlen()。
如果希望知道查詢是否應返回結果集,可使用mysql_field_count()進行檢查?25.2.3.22節(jié),“mysql_field_count()”?。
返回值
如果查詢成功,返回0。如果出現(xiàn)錯誤,返回非0值。
如果失敗,可使用mysql_error(MYSQL* mysql)看看錯誤信息。
使用mysql_query和mysql_real_query可以執(zhí)行任何的mysql語句。不需要在語句末尾加上分號!
對于沒有像select一樣的查詢,需要接著調用mysql_store_result或者mysql_use_result來保存結果集。
對于insert或者delete,create語句,不返回結果集的,判斷返回值看看是否執(zhí)行成功,然后用mysql_affected_rows函數來
查詢被影響的行數。用mysql_error(MYSQL* mysql)來看錯誤信息
c++操作mysql :查詢結果集
用mysql進行數據查詢的時候,mysql會返回一個結果集給我們。接著我們需要調用mysql的api,從這個結果集中取得我們要的數據。
取完數據之后,需要釋放這個結果集。
mysql的結果集其實就是一個MYSQL_RES結構,其定義如下:
typedef struct??st_mysql_res??{
my_ulonglong row_count; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 結果集的行數
unsigned int field_count, current_field; ?? ? ? ? ??// 結果集的列數,當前列
MYSQL_FIELD?*fields; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??// 結果集的列信息
MYSQL_DATA?*data; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??// 結果集的數據
MYSQL_ROWS?*data_cursor; ?? ? ? ? ? ? ? ? ? ? ??// 結果集的光標
MEM_ROOT?field_alloc; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 內存結構
MYSQL_ROW?row; ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 非緩沖的時候用到
MYSQL_ROW?current_row; ? ? ? ? ? ? ? ? ? ? ? ? ? //mysql_store_result時會用到。當前行
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的數據的鏈表節(jié)點??梢妋ysql的結果集是鏈表結構 typedef struct st_mysql_data { ??my_ulonglong rows; ??unsigned int fields; ??MYSQL_ROWS *data; ??MEM_ROOT alloc; }??MYSQL_DATA?; // 數據集的結構 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?; ?//列信息的結構
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?; //內存結構
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