adovc資料庫-ag真人国际官网
① vc中如何正確使用ado
當前各種主流資料庫有很多,包括oracle, ms sql server, sybase, informix, mysql, db2,
interbase / firebird, postgresql, sqlite, sap/db, timesten, ms access等等。資料庫編程是對資料庫的創建、讀寫等一列的操作。資料庫編程分為資料庫客戶端編程與資料庫伺服器端編程。資料庫客戶端編程主要使用odbc api、ado、ado.net、oci、otl等方法;資料庫服務端編程主要使用ole db等方法。
資料庫編程需要掌握一些訪問資料庫技術方法,還需要注意怎麼設計高效的資料庫、資料庫管理與運行的優化、資料庫語句的優化。
創建一個connection對象
打開數據源,建立同數據源的連接
執行一個sql命令
使用結果集
終止連接
連接對象(connection)
命令對象(command)
記錄集對象(recordset)
ado編程的一般步驟:
ado最重要的三個對象:
在使用這三個對象的時候,需要定義與之相對應的智能指針:_connectionptr、_commandptr、_recordsetptr
使用智能指針要:定義指針變數、創建其實例(實例化)、調用方法和屬性。該智能指針在析構對象時,自動調用release方法,即使用後不需要手動釋放內存,代碼更加簡潔。
但需要調用close方法,關閉連接connection或者記錄集recordset。
② 怎麼在vc 中用ado創建資料庫
vc 中使用ado方式操作access資料庫2005-12-1209:59來源:天極開發作者:劉濤責任編輯:方舟·yesky評論()ado(activexdataobject)是microsoft資料庫應用程序開發的新介面,是建立在oledb之上的高層資料庫訪問技術,即使你對oledb,com不了解也能輕松對付ado,因為它非常簡單易用,甚至比你以往所接觸的odbcapi、dao、rdo都要容易使用,並不失靈活性。本文詳細地介紹在visualc 開發環境下如何使用ado來進行資料庫應用程序開發,並給出示例代碼。為了使讀者朋友都能測試本例提供的代碼,我們採用access資料庫,您可以直接在我們提供的示例代碼中找到這個test。mdb。程序編譯運行後的效果如圖一所示:
圖一、ado操作acess資料庫的界面效果圖
一、實現方法
萬事開頭難,任何一種新技術對於初學者來說最重要的還是"入門",掌握其要點。讓我們來看看ado資料庫開發的基本流程吧!它的基本步驟如下:
(1)初始化com庫,引入ado庫定義文件
(2)用connection對象連接資料庫
(3)利用建立好的連接,通過connection、command對象執行sql命令,或利用recordset對象取得結果記錄集進行查詢、處理。
(4)使用完畢後關閉連接釋放對象。
下面我們將詳細介紹上述步驟並給出相關代碼。
1、com庫的初始化
我們可以使用afxoleinit()來初始化com庫,這項工作通常在cwinapp::initinstance()的重載函數中完成,請看如下代碼:
boolcadotest1app::initinstance()
{
afxoleinit();
。。。。。。
}
2、用#import指令引入ado類型庫
為了引入ado類型庫,需要在項目的stdafx。h文件中加入如下語句:
#import"c:\programfiles\commonfiles\system\ado\msado15。dll"
no_namespacerename("eof","adoeof")
這一語句有何作用呢?其最終作用同我們已經十分熟悉的#include類似,編譯的時候系統會為我們生成msado15。tlh,ado15。tli兩個c 頭文件來定義ado庫。
需要讀者朋友注意的是:您的開發環境中msado15。dll不一定在這個目錄下,請按實際情況修改;在編譯的時候可能會出現如下警告,對此微軟在msdn中作了說明,並建議我們不要理會這個警告:msado15。tlh(405):warningc4146:,resultstillunsigned。
3、創建connection對象並連接資料庫
為了首先我們需要添加一個指向connection對象的指針_connectionptrm_pconnection,下面的代碼演示了如何創建connection對象實例及如何連接資料庫並進行異常捕捉:
boolcadotest1dlg::oninitdialog()
{
cdialog::oninitdialog();
hresulthr;
try
{
hr=m_pconnection。createinstance("adodb。connection");///創建connection對象
if(succeeded(hr))
{
hr=m_pconnection->open("provider=microsoft。jet。oledb。4。0;
datasource=test。mdb","","",admodeunknown);///連接資料庫
//上面一句中連接字串中的provider是針對access2000環境的,對於access97,
//需要改為:provider=microsoft。jet。oledb。3。51;
}
}
catch(_com_errore)///捕捉異常
{
cstringerrormessage;
errormessage。format("連接資料庫失敗!\r\n錯誤信息:%s",e。errormessage());
afxmessagebox(errormessage);///顯示錯誤信息
}
在這段代碼中我們是通過connection對象的open方法來進行連接資料庫的,下面是該方法的原型:
hresultconnection15::open(_bstr_tconnectionstring,_bstr_tuserid,_bstr_tpassword,longoptions);
上述函數中參數connectionstring為連接字串;參數userid是用戶名;參數password是登陸密碼;參數options是連接選項,用於指定connection對象對數據的更新許可權,一般情況下options可以是如下幾個常量:
admodeunknown:預設。當前的許可權未設置
③ vc 用ado鏈接資料庫怎麼連
由於我也剛開始學,前幾天找到的,好使,我試過的,有什麼問題你可以問我
首先,要用#import語句來引用支持ado的組件類型庫(*.tlb),其中類型庫可以作為可執行程序(dll、exe等)的一部分被定位在其自身程序中的附屬資源里,如:被定位在msado15.dll的附屬資源中,只需要直接用#import引用它既可。可以直接在stdafx.h文件中加入下面語句來實現:
#import "c:\program files\common files\system\ado\msado15.dll" \
no_namespace \
rename ("eof", "adoeof")
其中路徑名可以根據自己系統安裝的ado支持文件的路徑來自行設定。當編譯器遇到#import語句時,它會為引用組件類型庫中的介面生成包裝類,#import語句實際上相當於執行了api涵數loadtypelib()。#import語句會在工程可執行程序輸出目錄中產生兩個文件,分別為*.tlh(類型庫頭文件)及*.tli(類型庫實現文件),它們分別為每一個介面產生智能指針,並為各種介面方法、枚舉類型,clsid等進行聲明,創建一系列包裝方法。語句no_namespace說明ado對象不使用命名空間,rename ("eof", "adoeof")說明將ado中結束標志eof改為adoeof,以避免和其它庫中命名相沖突。
其次,在程序初始過程中需要初始化組件,一般可以用coinitialize(null);來實現,這種方法在結束時要關閉初始化的com,可以用下面語句couninitialize();來實現。在mfc中還可以採用另一種方法來實現初始化com,這種方法只需要一條語句便可以自動為我們實現初始化com和結束時關閉com的操作,語句如下所示: afxoleinit();
接著,就可以直接使用ado的操作了。我們經常使用的只是前面用#import語句引用類型庫時,生成的包裝類.tlh中聲明的智能指針中的三個,它們分別是_connectionptr、_recordsetptr和_commandptr。下面分別對它們的使用方法進行介紹:
1、_connectionptr智能指針,通常用於打開、關閉一個庫連接或用它的execute方法來執行一個不返回結果的命令語句(用法和_commandptr中的execute方法類似)。
——打開一個庫連接。先創建一個實例指針,再用open打開一個庫連接,它將返回一個iunknown的自動化介面指針。代碼如下所示:
_connectionptr m_pconnection;
// 初始化com,創建ado連接等操作
afxoleinit();
m_pconnection.createinstance(__uuidof(connection));
// 在ado操作中建議語句中要常用try...catch()來捕獲錯誤信息,
// 因為它有時會經常出現一些意想不到的錯誤。jingzhou xu
try
{
// 打開本地access庫demo.mdb
m_pconnection->open("provider=microsoft.jet.oledb.4.0;data source=demo.mdb","","",admodeunknown);
}
catch(_com_error e)
{
afxmessagebox("資料庫連接失敗,確認資料庫demo.mdb是否在當前路徑下!");
return false;
}
——關閉一個庫連接。如果連接狀態有效,則用close方法關閉它並賦於它空值。代碼如下所示:
if(m_pconnection->state)
m_pconnection->close();
m_pconnection= null;
④ vc ado資料庫
1. 生成應用程序框架並初始化ole/com庫環境
創建一個標準的mfc appwizard(exe)應用程序,然後在使用ado資料庫的initinstance函數中初始化ole/com庫(因為ado庫是一個com dll庫)。
本例為:
bool cadotestdlg::oninitdialog()
{
::coinitialize(null); //初始化ole/com庫環境
}
程序最後要調用 ::couninitialize();//釋放程序佔用的com 資源。
另外:
m_precordset->close(); 注意!!!不要多次關閉!!!!!!!!!!!!
m_pconnection->close();
m_precordset = null;
m_pconnection = null;
2. 引入ado庫文件
使用ado前必須在工程的stdafx.h文件最後用直接引入符號#import引入ado庫文件,以使編譯器能正確編譯。代碼如下:
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("eof","adoeof")
ado類的定義是作為一種資源存儲在ado dll(msado15.dll)中,在其內部稱為類型庫。類型庫描述了自治介面,以及c++使用的com vtable介面。當使用#import指令時,在運行時visual c++需要從ado dll中讀取這個類型庫,並以此創建一組c++頭文件。這些頭文件具有.tli 和.tlh擴展名,讀者可以在項目的目錄下找到這兩個文件。在c++程序代碼中調用的ado類要在這些文件中定義。
程序的第三行指示ado對象不使用名稱空間。在有些應用程序中,由於應用程序中的對象與ado中的對象之間可能會出現命名沖突,所以有必要使用名稱空間。如果要使用名稱空間,則可把第三行程序修改為: rename_namespace("adons")。第四行代碼將ado中的eof(文件結束)更名為adoeof,以避免與定義了自己的eof的其他庫沖突。
3.利用智能指針進行資料庫操作
在caboutdlg頭文件中定義兩個ado智能指針類實例,並在對話框中加入一個listctrl。
class cadotestdlg : public cdialog
{
_connectionptr m_pconnection;
_recordsetptr m_precordset;
clistctrl m_list;
......
}
ado庫包含三個智能指針:_connectionptr、_commandptr和_recordsetptr。
_connectionptr通常被用來創建一個數據連接或執行一條不返回任何結果的sql語句,如一個存儲過程。
_commandptr返回一個記錄集。它提供了一種簡單的方法來執行返回記錄集的存儲過程和sql語句。在使用_commandptr介面時,可以利用全局_connectionptr介面,也可以在_commandptr介面里直接使用連接串。_recordsetptr是一個記錄集對象。與以上兩種對象相比,它對記錄集提供了更多的控制功能,如記錄鎖定、游標控制等。
在使用ado程序的事件響應中onbutton1加入以下代碼:
void cadotestdlg::onbutton1()
{
m_list.resetcontent();
m_pconnection.createinstance(_uuidof(connection)); //初始化connection指針
m_precordset.createinstance(_uuidof(recordset));//初始化recordset指針
try
{
m_pconnection->open("dsn=adotest","","",0); //連接叫作adotest的odbc數據源
//注意:這是連接不需要用戶id或密碼的open 函數
// 否則形式為 ->open("dsn=test;uid=sa;pwd=123;","","",0);
// 執行sql語句得到一個記錄集把其指針賦值給m_precordset
cstring strsql="select * from middle";
bstr bstrsql = strsql.allocsysstring();
m_precordset->open(bstrsql,(idispatch*)m_pconnection,adopendynamic,adlockoptimistic,adcmdtext);
//adopendynamic:動態 adlockoptimistic樂觀封鎖法 adcmdtext:文本查詢語句
while(!m_precordset->adoeof)//遍歷所有記錄
{
//取紀錄欄位值方式之一
_variant_t thevalue; //variant數據類型
thevalue = m_precordset->getcollect("big_name");//得到欄位big_name的值
if(thevalue.vt!=vt_null)
m_list.addstring((char*)_bstr_t(thevalue));
//將該值加入到列表控制項中
//取紀錄欄位值方式之二
// _bstr_t thevalue1=m_precordset->fields->getitem("big_name")->value;
// cstring temp=thevalue1.();
// m_list.addstring(temp);
//數據類型轉換
_variant_t vusername,vbirthday,vid,vold;
trace("id:%d,姓名:%s,年齡:%d,生日:%s\r\n",
vid.lval,(lpctstr)(_bstr_t)vusername,vold.lval,(lpctstr)(_bstr_t)vbirthday);
m_precordset->movenext();//轉到下一條紀錄
}
m_precordset->close();
m_pconnection->close();
}
catch (_com_error e)//異常處理
{
afxmessagebox(e.errormessage());
}
m_precordset->close(); //注意!!!不要多次關閉!!!!否則會出錯
m_pconnection->close();
m_precordset = null;
m_pconnection = null;
}
程序中通過_variant_t和_bstr_t轉換com對象和c++類型的數據, _variant_t類封裝了ole自治variant數據類型。在c 中使用_variant_t類要比直接使用variant數據類型容易得多。
好,編譯後該程序就能運行了,但記住運行前要創建一個叫adotest的odbc數據源。該程序將把表middle中的big_name欄位值顯示在列表控制項中。
4.執行sql命令並取得結果記錄集
為了取得結果記錄集,我們定義一個指向recordset對象的指針:_recordsetptr m_precordset;
並為其創建recordset對象的實例: m_precordset.createinstance("adodb.recordset");
sql命令的執行可以採用多種形式,下面我們一進行闡述。
(1)利用connection對象的execute方法執行sql命令
execute方法的原型如下所示:
_recordsetptr connection15::execute ( _bstr_t commandtext, variant * recordsaffected, long options )
其中commandtext是命令字串,通常是sql命令。
參數recordsaffected是操作完成後所影響的行數,
參數options表示commandtext中內容的類型,options可以取如下值之一:
adcmdtext:表明commandtext是文本命令
adcmdtable:表明commandtext是一個表名
adcmdproc:表明commandtext是一個存儲過程
adcmdunknown:未知
execute執行完後返回一個指向記錄集的指針,下面我們給出具體代碼並作說明。
_variant_t recordsaffected;
///執行sql命令:create table創建表格users,users包含四個欄位:整形id,字元串username,整形old,日期型birthday
m_pconnection->execute("create table users(id integer,username text,old integer,birthday datetime)",
&recordsaffected,
adcmdtext);
///往表格裡面添加記錄
m_pconnection->execute("insert into users(id,username,old,birthday) values (1, ''''washington'''',25,''''1970/1/1'''')",&recordsaffected,adcmdtext);
///將所有記錄old欄位的值加一
m_pconnection->execute("update users set old = old 1",&recordsaffected,adcmdtext);
///執行sql統計命令得到包含記錄條數的記錄集
m_precordset = m_pconnection->execute("select count(*) from users",&recordsaffected,adcmdtext);
_variant_t vindex = (long)0;
_variant_t vcount = m_precordset->getcollect(vindex);///取得第一個欄位的值放入vcount變數
上兩句可以寫成— _variant_t vcount = m_precordset->getcollect((_variant_t)((long)0));
m_precordset->close();///關閉記錄集
cstring message;
message.format("共有%d條記錄",vcount.lval);
afxmessagebox(message);///顯示當前記錄條數
(2)利用command對象來執行sql命令
_commandptr m_pcommand;
m_pcommand.createinstance("adodb.command");
_variant_t vnull;
vnull.vt = vt_error;
vnull.scode = disp_e_paramnotfound;///定義為無參數
m_pcommand->activeconnection = m_pconnection;///非常關鍵的一句,將建立的連接賦值給它
m_pcommand->commandtext = "select * from users";///命令字串
m_precordset = m_pcommand->execute(&vnull,&vnull,adcmdtext);///執行命令,取得記錄集
在這段代碼中我們只是用command對象來執行了select查詢語句,command對象在進行存儲過程的調用中能真正體現它的作用。下次我們將詳細介紹。
(3)直接用recordset對象進行查詢取得記錄集
實例——
void cgmsadlg::ondbselect()
{
// todo: add your control notification handler code here
_recordsetptr rs1; //定義recordset對象
_bstr_t connect("dsn=gms;uid=sa;pwd=;");//定義連接字元串
_bstr_t source ("select count(*) from buaa.mdb010"); //要執行的sql語句
::coinitialize(null); //初始化rs1對象
hresul hr = rs1.createinstance( __uuidof( recordset ) );
//省略對返回值hr的判斷
rs1->open( source,
connect,
adopenforwardonly,
adlockreadonly,
-1 );
_variant_t temp=rs1->getcollect(_variant_t((long)0));
cstring strtemp=(char* )(_bstr_t)temp;
messagebox("ok!" strtemp);
}
例如
m_precordset->open("select * from users",
_variant_t((idispatch *)m_pconnection,true),
adopenstatic,
adlockoptimistic,
adcmdtext);
open方法的原型是這樣的:
hresult recordset15::open ( const _variant_t & source,
const _variant_t & activeconnection,
enum cursortypeenum cursortype,
enum locktypeenum locktype,
long options )
其中:
①source是數據查詢字元串
②activeconnection是已經建立好的連接(我們需要用connection對象指針來構造一個_variant_t對象)
③cursortype游標類型,它可以是以下值之一,請看這個枚舉結構:
enum cursortypeenum
{
adopenunspecified = -1,///不作特別指定
adopenforwardonly = 0,///前滾靜態游標。這種游標只能向前瀏覽記錄集,比如用movenext向前滾動,這種方式可以提高瀏覽速度。但諸如bookmark,recordcount,absoluteposition,absolutepage都不能使用
adopenkeyset = 1,///採用這種游標的記錄集看不到其它用戶的新增、刪除操作,但對於更新原有記錄的操作對你是可見的。
adopendynamic = 2,///動態游標。所有資料庫的操作都會立即在各用戶記錄集上反應出來。
adopenstatic = 3///靜態游標。它為你的記錄集產生一個靜態備份,但其它用戶的新增、刪除、更新操作對你的記錄集來說是不可見的。
};
④locktype鎖定類型,它可以是以下值之一,請看如下枚舉結構:
enum locktypeenum
{
adlockunspecified = -1,///未指定
adlockreadonly = 1,///只讀記錄集
adlockpessimistic = 2,悲觀鎖定方式。數據在更新時鎖定其它所有動作,這是最安全的鎖定機制
adlockoptimistic = 3,樂觀鎖定方式。只有在你調用update方法時才鎖定記錄。在此之前仍然可以做數據的更新、插入、刪除等動作
adlockbatchoptimistic = 4,樂觀分批更新。編輯時記錄不會鎖定,更改、插入及刪除是在批處理模式下完成。
};
⑤options可以取如下值之一:
adcmdtext:表明commandtext是文本命令
adcmdtable:表明commandtext是一個表名
adcmdproc:表明commandtext是一個存儲過程
adcmdunknown:未知
5. 記錄集的遍歷、更新
根據我們剛才通過執行sql命令建立好的users表,它包含四個欄位:id,username,old,birthday
以下的代碼實現:打開記錄集,遍歷所有記錄,刪除第一條記錄,添加三條記錄,移動游標到第二條記錄,
更改其年齡,保存到資料庫。
_variant_t vusername,vbirthday,vid,vold;
_recordsetptr m_precordset;
m_precordset.createinstance("adodb.recordset");
m_precordset->open("select * from users",
_variant_t((idispatch*)m_pconnection,true),
adopenstatic,
adlockoptimistic,
adcmdtext);
while(!m_precordset->adoeof)
{
vid = m_precordset->getcollect(_variant_t((long)0));///取得第1列的值,從0開始計數,
///你也可以直接給出列的名稱,如下一行
vusername = m_precordset->getcollect("username");///取得username欄位的值
vold = m_precordset->getcollect("old");
vbirthday = m_precordset->getcollect("birthday");
///在debug方式下的output窗口輸出記錄集中的記錄
if(vid.vt != vt_null && vusername.vt != vt_null && vold.vt != vt_null && vbirthday.vt != vt_null)
trace("id:%d,姓名:%s,年齡:%d,生日:%s\r\n",
vid.lval,
(lpctstr)(_bstr_t)vusername,
vold.lval,
(lpctstr)(_bstr_t)vbirthday);
m_precordset->movenext();///移到下一條記錄
}
m_precordset->movefirst();///移到首條記錄
m_precordset->delete(adaffectcurrent);///刪除當前記錄
///添加三條新記錄並賦值
for(int i=0;i<3;i )
{
m_precordset->addnew();///添加新記錄
m_precordset->putcollect("id",_variant_t((long)(i 10)));
m_precordset->putcollect("username",_variant_t("葉利欽"));
m_precordset->putcollect("old",_variant_t((long)71));
m_precordset->putcollect("birthday",_variant_t("1930-3-15"));
}
m_precordset->move(1,_variant_t((long)adbookmarkfirst));///從第一條記錄往下移動一條記錄,即移動到第二條記錄處
m_precordset->putcollect(_variant_t("old"),_variant_t((long)45));///修改其年齡
m_precordset->update();///保存到庫中
備註:多次查詢可把查詢過程做成一個函數executesql讓m_precordset獲得連接指針m_pconnection查詢結果
void executesql(_connectionptr m_pconnection, _recordsetptr m_precordset,cstring strsql)
{
//執行select 語句
bstr bstrsql = strsql.allocsysstring();
try
{
m_precordset->open(bstrsql,(idispatch*)m_pconnection,adopendynamic,adlockoptimistic,adcmdtext);
//adopendynamic:動態 adlockoptimistic樂觀封鎖法 adcmdtext:文本查詢語句
}
catch(_com_error error)
{
cstring errormessage;
errormessage.format("%s",(lptstr)error.description());
afxmessagebox(errormessage);
}
}
//出錯處理:
3127——沒有找到目標表
3092——目標表已經存在
例如:
catch(const _com_error e)
{
afxmessagebox(e.description());
long errorcode=e.wcode();
if(3127==errorcode) afxmessagebox("表不存在");
if(3092==errorcode) afxmessagebox("表已經存在");
return false;
}
⑤ 請問vc6使用ado類進行資料庫操作如何提速
你可以試試看先用select all把記錄都獲得
然後不要每條更改完都update 而是全部更改完後再update
最耗時的部分就是update
另一種辦法是通過sql語句直接操作資料庫按具體規則對欄位更新,而不是取出後再操作每條記錄,這種不適合沒有規律的更新
⑥ vc中如何用ado連接區域網sql server資料庫
一、ado概述
ado是microsoft為最新和最強大的數據訪問範例 ole db 而設計的,是一個便於使用的應用程序層介面。ado 使您能夠編寫應用程序以通過 ole. db 提供者訪問和操作資料庫伺服器中的數據。ado 最主要的優點是易於使用、速度快、內存支出少和磁碟遺跡小。ado 在關鍵的應用方案中使用最少的網路流量,並且在前端和數據源之間使用最少的層數,所有這些都是為了提供輕量、高性能的介面。之所以稱為 ado,是用了一個比較熟悉的暗喻,ole 自動化介面。
ole db是一組」組件對象模型」(com) 介面,是新的資料庫低層介面,它封裝了odbc的功能,並以統一的方式訪問存儲在不同信息源中的數據。ole db是microsoft uda(universal data access)策略的技術基礎。ole db 為任何數據源提供了高性能的訪問,這些數據源包括關系和非關系資料庫、電子郵件和文件系統、文本和圖形、自定義業務對象等等。也就是說,ole db 並不局限於 isam、jet 甚至關系數據源,它能夠處理任何類型的數據,而不考慮它們的格式和存儲方法。在實際應用中,這種多樣性意味著可以訪問駐留在 excel 電子數據表、文本文件、電子郵件/目錄服務甚至郵件伺服器,諸如 microsoft exchange 中的數據。但是,ole db 應用程序編程介面的目的是為各種應用程序提供最佳的功能,它並不符合簡單化的要求。您需要的api 應該是一座連接應用程序和ole db 的橋梁,這就是 activex data objects (ado)。
二、在vc中使用ado(開發步驟如下:)
1、引入ado庫文件
使用ado前必須在工程的stdafx.h頭文件里用直接引入符號#import引入ado庫文件,以使編譯器能正確編譯。代碼如下所示:
用#import引入ado庫文件
#import "c:\program files\common files\system\ado\msado15.dll"no_namespaces rename("eof" adoeof")
這行語句聲明在工程中使用ado,但不使用ado的名字空間,並且為了避免常數沖突,將常數eof改名為adoeof。現在不需添加另外的頭文件,就可以使用ado介面了。
2、初始化ole/com庫環境
必須注意的是,ado庫是一組com動態庫,這意味應用程序在調用ado前,必須初始化ole/com庫環境。在mfc應用程序里,一個比較好的方法是在應用程序主類的initinstance成員函數里初始化ole/com庫環境。
bool cmyadotestapp::initinstance()
{
if(!afxoleinit())//這就是初始化com庫
{
afxmessagebox(「ole初始化出錯!」);
return false;
}
……
}
3、ado介面簡介
ado庫包含三個基本介面:_connectionptr介面、_commandptr介面和_recordsetptr介面。
_connectionptr介面返回一個記錄集或一個空指針。通常使用它來創建一個數據連接或執行一條不返回任何結果的sql語句,如一個存儲過程。使用_connectionptr介面返回一個記錄集不是一個好的使用方法。對於要返回記錄的操作通常用_recordserptr來實現。而用_connectionptr操作時要想得到記錄條數得遍歷所有記錄,而用_recordserptr時不需要。
_commandptr介面返回一個記錄集。它提供了一種簡單的方法來執行返回記錄集的存儲過程和sql語句。在使用_commandptr介面時,你可以利用全局_connectionptr介面,也可以在_commandptr介面里直接使用連接串。如果你只執行一次或幾次數據訪問操作,後者是比較好的選擇。但如果你要頻繁訪問資料庫,並要返回很多記錄集,那麼,你應該使用全局_connectionptr介面創建一個數據連接,然後使用_commandptr介面執行存儲過程和sql語句。
_recordsetptr是一個記錄集對象。與以上兩種對象相比,它對記錄集提供了更多的控制功能,如記錄鎖定,游標控制等。同_commandptr介面一樣,它不一定要使用一個已經創建的數據連接,可以用一個連接串代替連接指針賦給_recordsetptr的connection成員變數,讓它自己創建數據連接。如果你要使用多個記錄集,最好的方法是同command對象一樣使用已經創建了數據連接的全局_connectionptr介面
,然後使用_recordsetptr執行存儲過程和sql語句。
4、使用_connectionptr介面
_connectionptr主要是一個連接介面,取得與資料庫的連接。它的連接字元串可以是自己直接寫,也可以指向一個odbcdsn。
_connectionptr pconn;
if (failed(pconn.createinstance("adodb.connection")))
{
afxmessagebox("create instance failed!");
return;
}
cstring strsrc;
strsrc="driver=sql server;server=";
strsrc ="suppersoft";
strsrc =";database=";
strsrc ="mydb";
strsrc =";uid=sa;pwd=";
cstring strsql = "insert into student(no,name,sex,address) values(3,'aaa','male','beijing')";
_variant_t varsrc(strsrc);
_variant_t varsql(strsql);
_bstr_t bstrsrc(strsrc);
if (failed(pconn->open(bstrsrc,"","",-1)))
{
afxmessagebox("can not open database!");
pconn.release();
return;
}
colevariant vtoptional((long)disp_e_paramnotfound,vt_error);
pconn->execute(_bstr_t(strsql),&vtoptional,-1);
pconn.release();
afxmessagebox("ok!");
5、使用_recordsetptr介面(以連接sql server為例)
_recordsetptr pptr;
if (failed(pptr.createinstance("adodb.recordset")))
{
afxmessagebox("create instance failed!");
return false;
}
cstring strsrc;
strsrc="driver=sql server;server=";
strsrc ="210.46.141.145";
strsrc =";database=";
strsrc ="mydb";
strsrc =";uid=sa;pwd=";
strsrc ="sa";
cstring strsql = "select id,name,gender,address from personal";
_variant_t varsrc(strsrc);
_variant_t varsql(strsql);
if(failed(pptr->open(varsql,varsrc,adopenstatic,adlockoptimistic,adcmdtext)))
{
afxmessagebox("open table failed!");
pptr.release();
return false;
}
while(!pptr->getadoeof())
{
_variant_t varno;
_variant_t varname;
_variant_t varsex;
_variant_t varaddress;
varno = pptr->getcollect ("id");
varname = pptr->getcollect ("name");
varsex = pptr->getcollect ("gender");
varaddress = pptr->getcollect ("address");
cstring strno =(char *)_bstr_t(varno);
cstring strname =(char *)_bstr_t(varname);
cstring strsex =(char *)_bstr_t(varsex);
cstring straddress =(char *)_bstr_t(varaddress);
strno.trimright();
strname.trimright();
strsex.trimright();
straddress.trimright();
int ncount = m_list.getitemcount();
int nitem = m_list.insertitem (ncount,_t(""));
m_list.setitemtext (nitem,0,strno);
m_list.setitemtext (nitem,1,strname);
m_list.setitemtext (nitem,2,strsex);
m_list.setitemtext (nitem,3,straddress);
pptr->movenext();
}
pptr->close();
pptr.release();
6、使用_commandptr介面
_commandptr介面返回一個recordset對象,並且提供了更多的記錄集控制功能,以下代碼示例了使用_commandptr介面的方法:
代碼:使用_commandptr介面獲取數據
_commandptr pcommand;
_recordsetptr prs;
pcommand.createinstance(__uuidof(command));
pcommand->activeconnection=pconn;
pcommand->commandtext="select * from student";
pcommand->commandtype=adcmdtext;
pcommand->parameters->refresh();
prs=pcommand->execute(null,null,adcmdunknown);
_variant_t varvalue = prs->getcollect("name");
cstring strvalue=(char*)_bstr_t(varvalue);
7、關於數據類型轉換由於com對象是跨平台的,它使用了一種通用的方法來處理各種類型的數據,因此cstring 類和com對象是不兼容的,我們需要一組api來轉換com對象和c 類型的數據。_vatiant_t和_bstr_t就是這樣兩種對象。它們提供了通用的方法轉換com對象和c 類型的數據。