VC++下使用ADO訪問Access數據庫完整篇

1、在StdAfx.h中引入ADO類支持
方法是在StdAfx.h中增加下面兩句話:
#include <comdef.h>//如果需要則添加本句
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename ("EOF", "adoEOF")
2、初始化COM環境
在MFC中可以用AfxOleInit()或CoInitialize(NULL),該函數一般放在InitInstance()歷程裏。
非MFC使用用CoInitialize(NULL)。
卸載COM環境使用CoUnInitialize(),一般放在主程序的析構函數裏。
這樣我們就會三個指針可用:_ConnectionPtr、_RecordsetPtr和_CommandPtr,分別代表:
_ConnectionPtr接口返回一個記錄集或一個空指針,通常使用它來創建一個數據連接或執行一條不返回任何結果的SQL語句,對於要返回記 錄的操作通常使用_RecordserPtr來實現。而用 _ConnectionPtr操作時要想得到記錄條數得遍歷所有記錄,用_RecordserPtr則不需要。
_RecordsetPtr指針是一個記錄集對象。可以對記錄集提供了更多的控制功能。它不一定要使用一個已經創建的數據連接,可以用一個連接串代 替連接指針賦給 _RecordsetPtr的connection成員變量,讓它自己創建數據連接。如果你要使用多個記錄集,最好的方法是使用已經創建了數據庫連接的全 局_ConnectionPtr接口,然後使用_RecordsetPtr執行存儲過程和SQL語句。
_CommandPtr指針接口返回一個記錄集。CommandPtr提供了一種簡單方法來執行返回記錄集的存儲過程和SQL語句。可以利用全局 _ConnectionPtr接口,也可以在_CommandPtr接口裏直接使用連接串。一次或少量數據庫訪問操作,一般是直接使用連接串,如果需要頻 繁訪問數據庫,涉及返回多個記錄集,那麼,建議同_RecordsetPtr用法一樣,使用全局數據庫連接後,再使用_CommandPtr 接口執行存儲過程和SQL語句。
各指針的定義方法:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
_CommandPtr m_pCommand;
3、連接、關閉數據庫
1、連接數據庫
示例連接ACCESS,以昨天的FavorMan爲例。


    ::CoInitialize(NULL);//數據庫操作前先初始化COM環境


    CString strSQL;    //配置初始連接串
    strSQL="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=blogurl.mdb;";
    strSQL=strSQL+"Provider=Microsoft.Jet.OLEDB.4.0;"+"Data Source=blogurl.mdb;"+
        "Jet OLEDB:Database Password="+//str爲上面讀到數據庫路徑信息!
        DB_PASSWRD_STRING+";"+
        "Persist Security Info=False;";    //注意一定需要輸入四個\\\\才能表示"\\"
    //如果單獨輸入,必須形式爲"\\\\Abc\\db\\blogurl.mdb"格式!


    //--連接數據庫-----------------
    HRESULT hr;
    try
    {
        hr = m_pConnection.CreateInstance("ADODB.Connection");///創建Connection對象
        if(SUCCEEDED(hr))
        {
            hr = m_pConnection->Open((_bstr_t)strSQL,"","",adModeUnknown);///連接數據庫
            ///上面一句中連接字串中的Provider是針對ACCESS2000環境的,對於ACCESS97,需要改爲:Provider=Microsoft.Jet.OLEDB.3.51;  }
        }
    }
    catch(_com_error e)///捕捉異常
    {
        CString errormessage;
        errormessage.Format("連接數據庫失敗!\r\n錯誤:%s!",e.ErrorMessage());
        AfxMessageBox(errormessage);///顯示錯誤信息


        return FALSE;
    }
2、關閉數據庫


if( m_pConnection->State )//如果連接有效
        m_pConnection->Close();
m_pConnection = NULL;
4、數據庫訪問
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
try
{
        //打開數據庫
        m_pRecordset->Open("SELECT * FROM BlogUrl",
        m_pConnection.GetInterfacePtr(),//或使用_variant_t((IDispatch*)theApp.m_pConnection,true),,但需要extern聲明theApp;
        adOpenDynamic,
        adLockOptimistic,
        adCmdText);
        //遍歷讀取
       while(!m_pRecordset->adoEOF)//adoEOF判斷數據庫指針是否已經到結果集末尾;BOF判斷是否在第一條記錄前面
        {
            vID            =m_pRecordset->GetCollect("ID");
                //這裏已經讀到當前記錄的ID,需要進行非空等判斷,非空之後就可以處理,比如添加到列表框等。
        //....
            m_pRecordset->MoveNext();
        }
        m_pRecordset->Close();//關閉記錄集 
}
catch(_com_error error)
{
            CString errorMessage; 
            errorMessage.Format("%s",(LPTSTR)error.Description()); 
            AfxMessageBox(errorMessage);
}
取得某字段的值有兩種辦法,一種是指定該字段名,另一種是指定該字段的ID編號,從0開始。
假設上文的ID是從0開始,那麼可以採用:
m_pRecordset->GetCollect(_variant_t(long(0));
也可以採用:
pRecordset->get_Collect("ID");
其它索引值讀取類似處理。
 
附一些常用的執行語法:
1、添加記錄
a、調用m_pRecordset->AddNew();
b、調用m_pRecordset->PutCollect("ID",vID);給ID字段賦值
c、調用m_pRecordset->Update();//確認並刷新入庫
2、修改記錄
方法類似添加記錄,只是起初按照查詢指定記錄打開接口,比如SELECT * FROM ulist where ID=%d形式,不需要m_pRecordset->AddNew();,直接使用PutCollect("ID",vID)。
3、刪除記錄
刪除記錄只需要把記錄指針移動到要刪除的記錄上,然後調用m_pRecordset->Delete(adAffectCurrent)
移動到指定記錄上也有兩種方法,一種直接使用查詢指定記錄(需要唯一字段)方式定位,另一種是使用Move(index)方式。
下面例子是使用Move方式到指定記錄。
try
{
        m_pRecordset->MoveFirst();//如果是採用SELECT * FROM ulist where ID=5方式打開數據庫連接則不需要本句
       m_pRecordset->Move(5);//假設刪除第5條記錄,如果是採用SELECT * FROM ulist where ID=5方式打開數據庫連接則不需要本句
        m_pRecordset->Delete(adAffectCurrent);
        m_pRecordset->Update();
}
catch(_com_error error)
{
            CString errorMessage;
            errorMessage.Format("%s",(LPTSTR)error.Description());
            AfxMessageBox(errorMessage); 
}
4、_CommandPtr用法參考
a、_CommandPtr指針初始化
m_pCommand->ActiveConnection = m_pConnection;// 將庫連接賦於它,或單獨再創建也可以,根據實際需要定
m_pCommand->CommandText = "SELECT * FROM BlogUrll";
b、_CommandPtr與_RecordsetPtr配合讀取記錄集
m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText);//執行SQL語句,返回結果記錄集
c、直接使用_ConnectionPtr執行SQL語句
m_pConnection->Execute( _bstr_t CommandText,VARIANT * RecordsAffected,long Options )
例如:
m_pConnection->Execute("UPDATE BlogUrl SET ID= 1 WHERE ID = 5",&RecordsAffected,adCmdText);
5、遍歷數據庫中所有表名
m_pRecordset = m_pConnect->OpenSchema(adSchemaTables);
while(!(m_pRecordset ->adoEOF))
{
        _bstr_t tblname = m_pRecordset->Fields->GetItem("TABLE_NAME")->Value;//獲取表格
        _bstr_t tbltype = m_pRecordset->Fields->GetItem("TABLE_TYPE")->Value;//獲取表格類型
        //這裏可以對錶格類型進行判斷,判斷後即可處理tblname
        if (!strcmp(tbltype ,"TABLE"))
        {
                AfxMessageBox(tblname);
        }     
        m_pRecordset->MoveNext();
}
m_pRecordset->Close();
6、遍歷一個表中的所有字段
//方法1:
m_pRecordset = m_pConnect->OpenSchema(adSchemaColumns);
while(!(m_pRecordset ->adoEOF))
{
        _bstr_t colname = m_pRecordset->Fields->GetItem("COLUMN_NAME")->Value;//獲取字段名
          AfxMessageBox(colname);
        m_pRecordset->MoveNext();
}
m_pRecordset->Close();
 
//方法2:
FieldsPtr pFields = NULL;
HRESULT hr = m_pRecordset->get_Fields (&pFields);//得到記錄集的字段集
if(!SUCCEEDED(hr))        return;
int iColCount;
pFields->get_Count(&iColCount);//字段總數
BSTR        bstrColName;
for(int i=0;i<iColCount;i++)//按記錄集的各字段循環
{
        //pFields->GetItem(_variant_t(i))->get_Name(&bstrColName);
        pFields->Item(_variant_t(i))->get_Name(&bstrColName);//獲得字段名字
        CString csName=bstrColName;
        //pField->Item[i]->get_Type(&fType);//獲取字段類型
        //pField->Item[i]->get_DefinedSize(&lSize);//獲得字段的大小
       AfxMessageBox(csName);
}
if(NULL != hr)
        tblfields ->Release();//釋放指針
7、常用數據格式轉換
_variant_t var;
BSTR bvar;
CString csVar;
_bstr_t bstr;
_variant_t 轉化爲long型: (long)var;
_variant_t轉化爲 CString型: csVar= (LPCSTR)_bstr_t(var);
CString轉化爲_variant_t型: _variant_t(csVar);或(LPTSTR)(LPCTSTR)csVar;
CString轉化爲BSTR型: bvar= csVar.AllocSysString();
BSTR轉化爲CString型:csVar= (LPCSTR)bvar;
CString轉化爲_bstr_t型: bstr = (_bstr_t)csVar;
_bstr_t 轉化爲CString型:csVar= (LPCSTR)bstr;

發佈了24 篇原創文章 · 獲贊 18 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章