VC++中通過ADO中的_RecordsetPtr操作數據庫:增刪改查

_RecordsetPtr智能指針,它是專門爲通過記錄集操作數據庫而設立的指針,通過該接口可以對數據庫的表內的記錄、字段等進行各種操作。

要搞清楚:數據庫和ADO的記錄集是兩個不同的概念,是存在於不同物理位置的兩個存儲空間。記錄集相當於是實際數據的一份拷貝。正因爲記錄集是相對脫離數據庫而存在的,所以才存在後面將要介紹的Open方法中涉及的光標類型和鎖定類型這兩個問題。

_RecordsetPtr接口的使用方法:

先創建記錄集對象:

_ConnectionPtr m_pRecordset;

m_pRecordset.CreateInstance(__uuidof(Recorset));

創建記錄集對象後,只是爲它分配內存空間,記錄集中不含任何數據。記錄集對象是用來獲得數據庫中的數據並對其操作的,所以還要打開記錄集,從數據庫中取得數據記錄。可有多種方法打開記錄集,下面只介紹最常用的Open方法:

爲記錄集對象分配了空間後就可以用Open函數打開記錄集,該函數原型爲:

HRESULT Recordset15::Open(const_variant_t& Source,const_variant_t& ActiveConnection,enum CursorTypeEnumCursorType,enum LockTypeEnum LockType,long Options)

參數:

Source是數據查詢字符串。

ActiveConnection是已經建立好的連接(我們需要用Connection對象指針來構造一個_variant_t對象)。

CursorType 光標類型,它是枚舉CursorTypeEnum中的一個值。

LockType 鎖定類型 它是枚舉LockTypeEnum中的一個值

Options 指定Source的類型

光標類型CursorType,可取如下值之一:

adOpenUnspecified=-1 不作特別指定

adOpenForwardOnly=0默認值,前滾靜態光標。這種光標只能向前瀏覽記錄集,比如用MoveNext向前滾動,這種方式可節省資源,提高瀏覽速度,但諸如BookMark、RecordCount、AbsolutePosition、AbsolutePage都不能使用。

adOpenKeyset=1鍵集遊標,採用這種光標的記錄集看不到其它用戶的新增、刪除操作,但對於更新原有記錄的操作對你是可見的。

adOpenDynamic=2動態光標,所有數據庫的操作都會立即在用戶記錄集上反應出來。

adOpenStatic=3靜態遊標。它爲記錄產生一個靜態備份,其他用戶的新增、刪除、更新操作對你的記錄集來說是不可見的。

LockType鎖定類型,它可以是以下值之一,請看如下枚舉結構

enum LockTypeEnum

{

   adLockUnspecified=-1,

   //未指定

   adLockReadOnly=1,

   //只讀記錄集,默認值。無法更改數據。

   adLockPessimistic=2,

   //悲觀鎖定方式。只有在調用Update方法時才鎖定記錄。這是最安全的鎖定機制

   adLockOptimistc=3,

   //樂觀鎖定方式,只有在你調用Update方法時才鎖定記錄。

   在此之前仍然可以做數據的更新、插入、刪除等操作

adLockBatchOptimistic=4樂觀分批更新。編輯時記錄不會鎖定,更改、插入及刪除是在批處理模式下完成。

}

關於光標和鎖定類型,對於一般用戶,建議您只作簡單瞭解,後面將進一步進行解說。

Options可以取如下值之一:

adCmdText: 表明CommandText是文本命令。

adCmdTable:表明CommandText是一個表名。

adCmdProc:表明CommandText是一個存儲過程。

adCmdUnknown:未知。

例如:假設m_pConnection是我們已經建立好的連接,我們使用_RecordsetPtr接口的Open方法打開Employees表的記錄集的語句如下:

m_pRecordset->Open(“SELECT * FROMEmployees”,

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

例程RecordsetPtr演示使用_RecordsetPtr指針通過記錄集操作數據庫。

打開VC++6.0,新建一個基於對話框的工程RecordsetPtr。在對話框IDD_RECORDSETPTR_DIALOG中進行編輯:

使用三個GroupBox分成四個部分,第一部分演示如何讀取數據庫數據;第二部分演示如何修改數據庫;第三部分演示如何向數據庫中插入數據;第四部分演示如何刪除數據庫中的數據。

使用ClassWizard給列表框IDC_LIST1創建CListBox變量m_list1:

雙擊IDC_BTN_READREC按鈕,並編輯OnBtnReadrec()函數如下:

void CRecordsetPtrDlg::OnBtnReadrec()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

      errormessage.Format("連接數據庫失敗!\r錯誤信息:%s",e.ErrorMessage());

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECTEmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERECity='London'",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   _variant_tvEmployeeID,vFirstName,vLastName,vHireDate,vCity;

   try

   {

      while(!m_pRecordset->adoEOF)

      {

          vEmployeeID=m_pRecordset->GetCollect(_variant_t((long)0));

          //取得第1列的值,從0開始計數,你也可以直接列出列的名稱,如下一行

          vFirstName=m_pRecordset->GetCollect("FirstName");

          vLastName=m_pRecordset->GetCollect("LastName");

          vHireDate=m_pRecordset->GetCollect("HireDate");

          vCity=m_pRecordset->GetCollect("City");

          CString strtemp;

          if(vEmployeeID.vt!=VT_NULL)

          {

             strtemp.Format("%d",vEmployeeID.lVal);

          }

          if(vFirstName.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vFirstName;

          }

          if(vLastName.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vLastName;

          }

          if(vHireDate.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vHireDate;

          }

          if(vCity.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vCity;

          }

          m_list1.AddString(strtemp);

          

          m_list1.AddString("\n");

          m_pRecordset->MoveNext();

      }

      

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL; 

}

該段代碼演示瞭如何讀取數據庫表內的數據。其原理是如果沒有遇到表結束標誌adoEOF,則用GetCollect(字段名)來獲取當前記錄指針所指的字段值,然後再用MoveNext()方法移動到下一條記錄位置。

雙擊IDC_BTN_CHANGE按鈕,並編輯OnBtnChange()函數如下:

void CRecordsetPtrDlg::OnBtnChange()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

      errormessage.Format("連接數據庫失敗!\r錯誤信息:%s",e.ErrorMessage());

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECTEmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERE(City='London') AND (EmployeeID=6)",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   try

   {

      while(!m_pRecordset->adoEOF)

      {

          m_pRecordset->PutCollect("LastName",_variant_t("Jackson"));

          m_pRecordset->MoveNext();

      }

      m_pRecordset->Update();

   }

   catch(_com_error* e)

   {

      AfxMessageBox(e->ErrorMessage());

   }

   

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL;

}

該段代碼演示瞭如何修改記錄中的字段值:

將記錄指針移動到要修改記錄的位置處,直接用PutCollect(字段名,值)將新值寫入並Update()更新到數據庫即可。

移動記錄指針可以通過MoveFirst()方法移動到第一條記錄,MoveLast()方法移動到最後一條記錄,MovePrevious()方法移動到當前記錄的前一條記錄,MoveNext()方法移動到當前記錄的下一條記錄。也可以使用Move(記錄號)移動記錄指針到需要位置。注意:Move()方法是相對於當前記錄來移動指針位置的。正值向後移動,負值向前移動。如Move(3),當前記錄是3時,它將從記錄3開始往後再移動3條記錄位置。關於移動記錄指針後面將會用到。

雙擊IDC_BTN_NEW按鈕,並編輯OnBtnNew()函數如下:

void CRecordsetPtrDlg::OnBtnNew()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

      errormessage.Format("連接數據庫失敗!\r錯誤信息:%s",e.ErrorMessage());

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECT * FROMEmployees",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   try

   {

      m_pRecordset->MoveLast();

      m_pRecordset->AddNew();

      m_pRecordset->PutCollect("EmployeeID",_variant_t((long)10));

      m_pRecordset->PutCollect("FirstName",_variant_t("Mary"));

      m_pRecordset->PutCollect("LastName",_variant_t("Williams"));

      m_pRecordset->PutCollect("HireDate",_variant_t("15/4/199312:00:00"));

      m_pRecordset->PutCollect("City",_variant_t("NewYork"));

      m_pRecordset->PutCollect("Country",_variant_t("USA"));

   }

   

   catch(_com_error *e)

   {

      AfxMessageBox(e->ErrorMessage());

   }

   

   m_pRecordset->Update();

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL;

}

該段代碼演示如何插入記錄:

先用AddNew()方法新增一個空記錄,再用PutCollect(字段名,值)輸入每個字段的值,最後用Update()更新到數據庫即可。

雙擊IDC_BTN_DELETE按鈕,並編輯OnBtnDelete()函數如下:

void CRecordsetPtrDlg::OnBtnDelete()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

      errormessage.Format("連接數據庫失敗!\r錯誤信息:%s",e.ErrorMessage());

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECT * FROMEmployees",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   try

   {

      //假設刪除第10條記錄

      m_pRecordset->MoveFirst();

      m_pRecordset->Move(9)   //從當前記錄向後再移動9條記錄

      m_pRecordset->Delete(adAffectCurrent);

      //參數adAffectCurrent爲刪除當前記錄

      m_pRecordset->Update();

   }

   catch(_com_error *e)

   {

      AfxMessageBox(e->ErrorMessage());

   }

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL; 

}

該段代碼演示瞭如何刪除記錄:

先將記錄指針移動到要刪除的記錄的位置,直接用Delete()方法刪除它,並用Update()來更新數據庫即可。

使用記錄集操作完畢後要關閉記錄集:

直接用Close()方法關閉記錄集並賦予其空值。代碼如下:

m_pRecordset->Close();

m_pConnection->Close();

m_pRecordset=NULL;

m_pConnection=NULL;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章