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開發應用程序有兩種方法,一種是直接在應用程序中使用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對話框中自動生成的靜態文本,然后在該對話框的編輯窗口中擊鼠標右鍵,在彈出的快捷菜單中選擇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。   
這中方法盡管簡單,但是對數據庫的訪問效率較低,使用起來也不靈活,程序員對數據庫的控制較少,不能最大限度的發揮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") //引入動態鏈接庫   
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對話框中自動生成的靜態文本;   
步驟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”開頭的4個ULONG類型的變量是對應字段的狀態值,用於判斷數據的捆綁是否成功,后面的程序代碼中將看到其應用。用於數據捆綁和映射的宏在頭文件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 被映射字段的狀態值   
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環境和建立與數據庫的連接,在析構函數中清除COM環境和釋放有關變量。在CAdoClsDoc類構造函數中添加如下內容:   
::CoInitialize(NULL);//初始化COM環境   
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");   
    
//創建對象實例   
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環境   
注意:在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.運行上面的程序,試着改變數據庫中的某個列的數值,讀者將會發現,在數據記錄的移動時,數據庫並沒有被更新。這是因為本程序所涉及到的四個字段中,其中有一個標識列,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函數進行數據類型的轉換。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM