VC中使用ADO的方法
ADO中打開一個連接:
pConnection->ConnectionString?= "這里的字符串有下面四種寫法"; //對連接字符串賦值
pConnection->Open(ConnectionString,"","",adModeUnknown);? //連接數據庫
第二三個參數分別為用戶的ID與密碼,因為在連接字符串ConnectionCstring中已經設置好了,這里可以為空。
第四個參數可以取下面兩個參數:adAsyncConnect,異步打開數據庫,在ASP中直接用16。 ? adConnectUnspecified,同步打開數據庫,在ASP中直接用-1。
?
ConnectionString根據不同的數據源,分別對應不同的寫法(要記下來很困難,可以在VB中利用ADO控件先連接好,再將其拷貝在VC中,這樣不容易出錯)
1)訪問Access 2000
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassWord"
2)訪問ODBC數據
"Provider=MADASQL;DSN=dsnName;UID=userName;PWD=userPassword;"
3)訪問Oracle數據庫
“Provider=MSDAORA;Data Sourse=serverName;User ID=userName;Password=userPassword;"
4)訪問MS SQL數據庫
"Provider=SQLOLEDB,Data Source=serverName;Initial Catalog=databaseName;User ID=userName;Password=userPassword;"
使用ADO開發(fā)應用程序有兩種方法,一種是直接在應用程序中使用ADO數據控件,該方法最簡單,無需編寫一行代碼即可實現對數據庫的訪問,另一種方法是直接使用ADO對象實現對數據庫的操作,該方法較復雜,但可以讓程序員更深入的控制數據庫。???
一.使用ActiveX控件建立應用程序???
該方法需要兩個ActiveX控件:Microsoft?? ADO?? Data?? Control?? ,version?? 6.0(OLE?? DB)和Microsoft?? ADO?? DataGrid?? Control?? ,version?? 6.0(OLE?? DB)。下面我們就使用這兩個控件,建立一個訪問SQL?? Server?? 7.0數據庫的應用程序,步驟如下:???
1.啟動VC6.0,使用MFC?? AppWizard建立一個單文檔應用程序,命為AdoCtl,在Step1到Step?? 5中使用缺設置,直接按Next即可,在Step?? 6中,選擇視圖類的基類為CFormView,然后按Finish,按OK,生成應用程序框架;???
2.在應用程序的ResourceView中,刪除IDD_ADOCTL_FORM對話框中自動生成的靜態(tài)文本,然后在該對話框的編輯窗口中擊鼠標右鍵,在彈出的快捷菜單中選擇Insert?? ActiveX?? Control...命令;???
3.在接下來的Insert?? ActiveX?? Control對話框中選擇Microsoft?? ADO?? Data?? Control?? ,version?? 6.0(OLE?? DB),按OK,就可以將該控件插入到對話框中。???
4.重復步驟2、3,在對話框中插入Microsoft?? ADO?? DataGrid?? Control?? ,version?? 6.0(OLE?? DB)控件;???
5.選中Data控件,擊右鍵,設置該控件的屬性;???
6.選擇Control頁面,該屬性頁要連接的數據源,其中提供了3種連接數據源的方法:???
a.使用數據連接文件(Use?? Data?? Link?? File);???
b.使用ODBC數據源(Use?? ODBC?? Data?? Source?? Name);???
c.使用連接字符串(Use?? Connection?? String).。???
在本程序中,我們使用連接字符串,連接SQL?? Server7.0數據庫。連接字符串中包含了程序與數據源的連接信息,其形式為Argument=Value,每個連接字符串可以包含多個Argument=Value表達式,不同的表達式之間以分號間隔,如訪問SFJ55.MDB數據庫的連接字符串可以寫成如下形式:???
Provider=Microsoft.Jet.OLEDB.4.0;Data?? Source=e:\\sfj55.mdb???
ADO支持如下的四種連接字符串的屬性設置:???
????
????
????
選擇Use?? Connection?? String選項,按Build...鈕,在數據鏈接屬性對話框中選擇OLE?? DB?? Provider(OLE?? DB提供者),此處我們選擇Microsoft?? OLE?? DB?? Provider?? for?? SQL?? Server,按下一步;???
7.在連接屬性頁中輸入服務器名稱,筆者使用NT工作站,名稱為BUILDER,SQL?? Server裝在本機,故此處服務器名稱為BUILDER,再選擇使用Windows?? NT集成安全設置,在服務器上選擇數據庫,筆者選擇DcProduct,這是一個存放生產明細的數據庫。測試連接成功后按確定。也可以選擇SQL?? Server?? 7.0自帶的其他數據庫和數據表。???
8.選擇Data控件屬性的RecordSource屬性頁,其中Command?? Type?? 中有4個選項:???
????
????
對于SQL語句和數據表名,使用過Access97的讀者一定很熟悉,至于存儲過程的有關信息請參考SQL?? Server的有關書籍。此處我們選擇2-adCmdTable,表名選擇[SFJ55-27-00-000MX](注意在表名兩邊加中括號),關閉屬性對話框。Data控件屬性設置完畢;???
9.選擇DataGrid控件,擊右鍵,設置該控件的屬性;???
10.選擇All屬性頁,設置DataSource屬性,設置為Data控件的ID號,即IDC_ADODC1,關閉屬性對話框;???
11.編譯并運行應用程序,即可在DataGrid控件中顯示數據表SFJ55-27-00-000MX中的數據。???
到此為止,我們在VC6.0中使用ADO技術建立的最簡單的應用程序已經完成,整個過程中沒有編寫一行代碼。只是該程序只能瀏覽和修改數據,不能對記錄進行添加和刪除。如果想增加充足添加和刪除記錄的功能,在DataGrid控件的All屬性頁中,設置AllowAddNew和AllowDelete屬性為TRUE。???
這中方法盡管簡單,但是對數據庫的訪問效率較低,使用起來也不靈活,程序員對數據庫的控制較少,不能最大限度的發(fā)揮ADO技術高速靈活的特點。下面通過一個實例來介紹在VC6.0中使用ADO對象訪問SQL?? Server數據庫。???
二.使用ADO對象建立數據庫應用程序???
在VC中使用過DAO的讀者對于CDaoWorkspace,CDaoDatabase,CDaoRecordset,CDaoTableDef等MFC類應該非常熟悉,然而,遺憾的是VC中并沒有提供有關ADO對象的類,那么我們將怎樣使用ADO對象呢?實際上,這可以通過在應用程序中使用預編譯指令#import來引入相關類的指針。在使用ADO對象之前必須首先在程序中加入如下的代碼:???
????
#define?? INITGUID //定義有關的變量???
#import?? "C:\program?? files\common?? files\system\ado\msado15.dll"rename_namespace("ADOCG")rename("EOF","EndOfFile") //引入動態(tài)鏈接庫???
using?? namespace?? ADOCG;???
#include?? "icrsint.h" //包含頭文件???
????
以上代碼在程序的運行過程中將產生名為msado15.tlh的頭文件,該頭文件中定義了一些有用的智能指針,以下是該文件關于智能指針定義的一段代碼:???
//???
//?? Smart?? pointer?? typedef?? declarations???
//???
????
......???
_COM_SMARTPTR_TYPEDEF(Properties,?? __uuidof(Properties));???
_COM_SMARTPTR_TYPEDEF(Property,?? __uuidof(Property));???
_COM_SMARTPTR_TYPEDEF(Error,?? __uuidof(Error));???
_COM_SMARTPTR_TYPEDEF(Errors,?? __uuidof(Errors));???
_COM_SMARTPTR_TYPEDEF(_Connection,?? __uuidof(_Connection));???
_COM_SMARTPTR_TYPEDEF(_Recordset,?? __uuidof(_Recordset));???
_COM_SMARTPTR_TYPEDEF(Fields,?? __uuidof(Fields));???
_COM_SMARTPTR_TYPEDEF(Field,?? __uuidof(Field));???
_COM_SMARTPTR_TYPEDEF(_Parameter,?? __uuidof(_Parameter));???
_COM_SMARTPTR_TYPEDEF(Parameters,?? __uuidof(Parameters));???
_COM_SMARTPTR_TYPEDEF(_Command,?? __uuidof(_Command));???
......???
這是基于ADO的支持類_com_ptr_t的一些指針的定義,其中宏_COM_SMARTPTR_TYPEDEF()在VC6.0頭文件COMDEF.H中定義。???
下面是我們經常使用的幾個智能指針:???
_ConnectionPtr?? 連接對象指針???
_RecordsetPtr 記錄集對象指針???
_ParameterPtr 參數對象指針???
_CommandPtr?? 命令對象指針???
FieldPtr 域對象指針???
PropertyPtr 屬性對象指針???
ErrorPtr 錯誤對象指針???
下面在一個程序實例中說明這些指針的用法,程序訪問的數據庫為SQL?? Server?? 7.0中自帶的NothWind,數據表名為Employees,這里只訪問EmployeeID,LastName,FirstName,Title等4個字段:???
步驟1.啟動VC6.0,使用MFC?? AppWizard建立一個單文檔應用程序,命為AdoCls,在Step1到Step?? 5中使用缺設置,直接按Next即可,在Step?? 6中,選擇視圖類的基類為CFormView,然后按Finish,按OK,生成應用程序框架,在應用程序的ResourceView中,刪除IDD_ADOCLS_FORM對話框中自動生成的靜態(tài)文本;???
步驟2.新建一個文本文件,并在其中輸入如下內容,然后將其保存為MyData.h,再將其添加到AdoCls工程中(菜單命令:Project\Add?? To?? Project\Files...),輸入內容如下:???
//MyData.h???
#define?? INITGUID???
#import?? "C:\program?? files\common?? files\system\ado\msado15.dll"rename_namespace("ADOCG")rename("EOF","EndOfFile")???
using?? namespace?? ADOCG;???
#include?? "icrsint.h"???
????
#if?? _MSC_VER?? >?? 1000???
#pragma?? once???
#endif?? //?? _MSC_VER?? >?? 1000???
????
class?? CMyRecord?? :?? public?? CADORecordBinding???
{???
BEGIN_ADO_BINDING(CMyRecord?? ) //開始數據捆綁???
ADO_FIXED_LENGTH_ENTRY(1,adInteger,m_id,lid,TRUE);???
ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_lastname,sizeof(m_lastname),llastname,TRUE)???
ADO_VARIABLE_LENGTH_ENTRY2(3,adVarChar,m_firstname,sizeof(m_firstname),lfirstname,TRUE)???
ADO_VARIABLE_LENGTH_ENTRY2(4,adVarChar,m_title,sizeof(m_title),ltitle,TRUE)???
END_ADO_BINDING() //結束數據捆綁???
public:???
long?? m_id;???
ULONG?? lid;???
char?? m_lastname[20];???
ULONG?? llastname;???
char?? m_firstname[10];???
ULONG?? lfirstname;???
char?? m_title[30];???
ULONG?? ltitle;???
????
};???
????
在MyData.h頭文件中定義了一個CMyRecord類,該類的基類必須是CADORecordBinding,且沒有構造函數和析構函數,只有一組用于數據捆綁和映射的宏和一組變量。其中以“m_”開頭的4個變量分別對應數據表Employees中EmployeeID,LastName,FirstName,Title等4個字段,它們將用于存取這4個字段的實際值,以“l(fā)”開頭的4個ULONG類型的變量是對應字段的狀態(tài)值,用于判斷數據的捆綁是否成功,后面的程序代碼中將看到其應用。用于數據捆綁和映射的宏在頭文件icrsint.h中定義,數據的捆綁和映射主要用到如下的幾個宏:???
(1).?? BEGIN_ADO_BINDING?? ()和?? END_ADO_BINDING()???
BEGIN_ADO_BINDING()宏的參數是用戶自定義的用于數據捆綁的記錄集類,本例中為CMyRecord。END_ADO_BINDING()宏不帶參數。???
(2).?? ADO_FIXED_LENGTH_ENTRY()宏,該宏用于數據庫中所有長度固定的字段,如Date/Time,BOOL,int,或定長的字符型字段。有兩個版本:???
(1)#define?? ADO_FIXED_LENGTH_ENTRY(Ordinal,DataType,Buffer,Status,Modify);???
(2)#define?? ADO_FIXED_LENGTH_ENTRY2(Ordinal,DataType,Buffer,,Modify);???
(3).?? ADO_NUMERIC_ENTRY(),用于數值型字段。也有兩個版本:???
(1)#define?? ADO_NUMERIC_ENTRY(Ordinal,DataType,Buffer,Precision,Scale,Status,Modify);???
(2)#define?? ADO_NUMERIC_ENTRY(Ordinal,DataType,Buffer,Precision,Scale,Modify);???
(4).ADO_VARIABLE_LENGTH_ENTRY(),有四個版本:???
(1)#define???? ADO_VARIABLE_LENGTH_ENTRY(Ordinal,DataType,Buffer,Size,Status,Length,Modify);???
(2)#define???? ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,DataType,Buffer,Size,Status,Modify);???
(3)#define???? ADO_VARIABLE_LENGTH_ENTRY3(Ordinal,DataType,Buffer,Size,Length,Modify);???
(4)#define???? ADO_VARIABLE_LENGTH_ENTRY4(Ordinal,DataType,Buffer,Size,Modify);???
Ordinal 被訪問的記錄集中的字段的序號,數據表Employees中EmployeeID,LastName,FirstName,Title等4個字段的序號分別為1、2、3、4;???
DataType 字段數據類型,見頭文件msado15.tlh(在程序的運行過程中將產生);???
Buffer 字段中的值所要映射到的變量???
Status 被映射字段的狀態(tài)值???
Modify 是否允許修改???
Precision 字段值的精度(數值型)???
Scale 字段值的數值范圍(數值型)???
Size 變長度字段值的長度(如:字符串)???
步驟3.進入ResourceView,在IDD_ADOCLS_FORM對話框中添加如下圖所示幾個控件:???
????
????
4個文本框控件對應的變量分別是m_id,m_firstname,m_lastname,m_title,這4個變量均屬于CAdoClsView類。???
步驟4.在CAdoClsDoc類頭文件包含MyRecord.h,并在其中添加如下幾個私有成員變量:???
private:???
CMyRecord?? m_rsRecSet;???
_RecordsetPtr?? m_pRs;???
IADORecordBinding?? *?? m_piAdoRecordBinding;???
CString?? m_strCmdText;???
CString?? m_strConnection;???
HRESULT?? hr;???
步驟5.在文檔類構造函數中初始化COM環(huán)境和建立與數據庫的連接,在析構函數中清除COM環(huán)境和釋放有關變量。在CAdoClsDoc類構造函數中添加如下內容:???
::CoInitialize(NULL);//初始化COM環(huán)境???
m_piAdoRecordBinding=NULL;???
m_strConnection=_T("Provider=SQLOLEDB.1;Integrated?? Security=SSPI;Persist?? Security?? Info=False;Initial?? Catalog=Northwind;Data?? Source=BUILDER");???????
m_strCmdText=_T("select?? EmployeeID,LastName,FirstName,Title?? from?? Employees");???
????
//創(chuàng)建對象實例???
m_pRs.CreateInstance(__uuidof(Recordset));???
//利用智能指針打開記錄集???
m_pRs->Open(LPCTSTR(m_strCmdText),LPCTSTR(m_strConnection),adOpenDynamic,adLockOptimistic,adCmdText);???
hr=m_pRs->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&m_piAdoRecordBinding);???
hr=m_piAdoRecordBinding->BindToRecordset(&m_rsRecSet);//與CMyRecord記錄類捆綁???
//此處,變量hr僅僅是用來判函數的調用是否成功,如果成功則hr等于0,否則hr小于0。???
在CAdoClsDoc類析構函數中添加如下內容:???
//在析構函數中關閉與數據源的連接,釋放有關變量???
if(m_pRs)m_pRs->Close();???
if(m_piAdoRecordBinding)m_piAdoRecordBinding->Release();???
m_pRs=NULL;???
CoUninitialize();//清除COM環(huán)境???
注意:在ADO中,獲得記錄集的方法有大約3種:1.通過連接對象的Execute()方法;2.通過命令對象的Execute()方法(但是,該命令對象必須首先與連接對象建立關聯pCmd->ActiveConnection=);3.直接建立并打開記錄集對象(在這種方法里面,其Open()函數中的ActiveConnection參數既可以是連接對象指針,又可以是連接字符串)。因此,使用ADO技術訪問數據庫的數據是非常自由的,不象DAO,必須先建立Database對象,然后再建立Recordset對象。我們這里采用第3中方法,這種方法只適用與簡單的應用中,如果在應用中需要訪問多哥數據源,則必須采用1和2兩種方法顯式的建立連接,以加快訪問速度。???
步驟6.在文檔類中添加記錄集的Move類函數,MoveFirst()、MovePrevious()、MoveNext()、MoveLast()、AddNew()、CreateBlankRecord():???
void?? CAdoClsDoc::MoveFirst()???
{???
if(m_pRs->Supports(adUpdate))???
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);???
m_pRs->MoveFirst();???
}???
????
void?? CAdoClsDoc::MovePrevious()???
{???
if(!m_pRs->BOF)???
{???
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);???
m_pRs->MovePrevious();???
}???
}???
????
void?? CAdoClsDoc::MoveNext()???
{???
if(!m_pRs->EndOfFile){???
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);???
m_pRs->MoveNext();???
}???
}???
????
void?? CAdoClsDoc::MoveLast()???
{???
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);???
m_pRs->MoveLast();???
}???
步驟7.在CAdoClsDoc類中添加GetMyRecord()函數:???
CMyRecord?? *?? CAdoClsDoc::GetMyRecord()???
{???
return(&m_rsRecSet);???
}???
步驟8.在void?? CAdoClsView::OnInitialUpdate()函數中添加如下代碼:???
{.......???
RefreshBoundData();}???
步驟9.在CAdoClsView類中添加RefreshBoundData()函數及其實現代碼:???
void?? CAdoClsView::RefreshBoundData()???
{???
CMyRecord?? *?? pRs;???
pRs=GetDocument()->GetMyRecord();???
m_firstname=adFldOK==pRs->lfirstname?pRs->m_firstname:"";???
m_lastname=adFldOK==pRs->llastname?pRs->m_lastname:"";???
m_title=adFldOK==pRs->ltitle?pRs->m_title:"";???
UpdateData(FALSE);???
}???
步驟10.在CAdoClsView類中添加UpdateBoundData()函數及其實現代碼:???
void?? CAdoClsView::UpdateBoundData()???
{???
CMyRecord?? *?? pRs;???
pRs=GetDocument()->GetMyRecord();???
UpdateData(TRUE);???
if(pRs->m_id!=m_id)???
pRs->m_id=m_id;???
if(pRs->m_firstname!=m_firstname)???
strcpy(pRs->m_firstname,LPCTSTR(m_firstname));???
??? if(pRs->m_lastname?? !=?? m_lastname)???
strcpy(pRs->m_lastname,LPCTSTR(m_lastname));???
if(pRs->m_title?? !=m_title)???
strcpy(pRs->m_title?? ,LPCTSTR(m_title));???
}???
步驟10.在CAdoClsView類中添加IDD_ADOCLS_FORM對話框中四個按鈕對應的消息映射函數:???
void?? CAdoClsView::OnButtonFirst()?????
{ UpdateBoundData();???
GetDocument()->MoveFirst?? ();???
RefreshBoundData();???
}???
void?? CAdoClsView::OnButtonLast()?????
{ UpdateBoundData();???
GetDocument()->MoveLast?? ();???
RefreshBoundData();???
}???
void?? CAdoClsView::OnButtonNext()?????
{ UpdateBoundData();???
GetDocument()->MoveNext?? ();???
RefreshBoundData();???
}???
void?? CAdoClsView::OnButtonPrevious()?????
{ UpdateBoundData();???
GetDocument()->MovePrevious?? ();???
RefreshBoundData();???
}???
步驟11.編譯運行該應用程序,即可實現對數據庫的瀏覽。???
使用ADO在VC6中建立數據庫應用程序,至此結束,關于這一方法以及本程序例子,作以下幾點說明:???
1.運行上面的程序,試著改變數據庫中的某個列的數值,讀者將會發(fā)現,在數據記錄的移動時,數據庫并沒有被更新。這是因為本程序所涉及到的四個字段中,其中有一個標識列,EmployeeID,標識列具有自動增長的特性,用戶不能更新,否則將出錯,這時,語句hr=m_piAdoRecordBinding->Update(&m_rsRecSet);將返回一個負值,即hr<0,讀者可以SQL?? Server?? 7中的Enterprise?? Manager打開NothWind數據庫,修改其中的數據表Employees,在該表的設計視圖中將其EmployeeID所在行的Identify復選框取消,然后保存。這時用戶即可實現對數據庫的更新。在調試時注意一下語句hr=m_piAdoRecordBinding->Update(&m_rsRecSet),hr將等于0。???
2.CMyRecord類的基類是CADORecordBinding,IADORecordBinding?? 是CADORecordBinding類的一個COM接口,它也是記錄集類CADORecordBinding的一部分,用戶可以通過該接口實現數據的捆綁、更新和添加,它對應3個(僅有3個)函數:BindToRecordset()、AddNew()和Update(),這三個函數可以參見頭文件icrsint.h。其中BindToRecordset()和Update()我們已經使用過,AddNew()的用法與Update()很相似,首先,將MyRecord類中各個數值變量(以m_開頭)賦初值,然后調用m_piAdoRecordBinding->AddNew(&m_rsRecSet)和m_pRs->MoveLast()(將記錄指針移到新添加的空白記錄處),即可實現記錄的添加功能。???
3.在宏ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,DataType,Buffer,Size,Status,Modify);中,第一個參數Ordinal指的是在當前記錄集中字段的位置,而不是原數據表中該字段的位置。如本程序中的LastName字段,在程序中所要訪問的記錄集中的位置是2,如果將記錄集改為:“select?? LastName,FirstName,Title?? from?? Employees”,則LastName的位置將為1,Ordinal=1。???
4.如果讀者不喜歡數據捆綁的方式訪問數據庫,ADO提供了對記錄集中單個域進行訪問的方法,如以下代碼可以更新當前記錄中的FirstName字段:???
_variant_t?? vFld,vValue;???
vFld.SetString("FirstName");???
vValue.SetString("Rose?? Tom");???
m_pRs->Update(vFld,vValue);???
以下代碼可以取得FirstName字段值:???
_variant_t?? vValue;???
CString?? strValue;???
vValue=m_pRs->GetCollect(_variant_t?? ("FirstName"));???
vValue.ChangeType(VT_BSTR);???
strValue=vValue.bstrVal;???
這種直接訪問字段值的方法很靈活,缺點是編程人員必須頻繁的調用ChangeType函數進行數據類型的轉換。
轉載于:https://www.cnblogs.com/renyuan/archive/2012/08/02/2620713.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的VC中使用ADO的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle的resouce、unlim
- 下一篇: 计算机毕业设计基于asp.net企业差旅