ADO中記錄集recordSet的使用


_RecordsetPtr使用方法

_variant_t vUsername,vID,vname; //變量聲明
_RecordsetPtr m_pRecordset;     //記錄集
CString strid;
_ConnectionPtr connection;
m_pRecordset.CreateInstance(__uuidof( Recordset )); //創建實例
m_pRecordset->Open("SELECT * FROM users",connection.GetInterfacePtr

(),adOpenStatic,adLockOptimistic,adCmdText);//執行SQL語句,得到記錄集, connection必須已和數

據庫連接

/*************原型*****************/
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,樂觀分批更新。編輯時記錄不會鎖定,更改、插入及刪除是在批處理模式

下完成。
};
5.option可以取以下值 
adCmdText:表明CommandText是文本命令
adCmdTable:表明CommandText是一個表名
adCmdProc:表明CommandText是一個存儲過程
adCmdUnknown:未知

/******************************************************/

while(!m_pRecordset->adoEOF)///這里為什么是adoEOF而不是EOF呢?還記得rename("EOF","adoEOF")這

一句嗎?
{
vID = m_pRecordset->GetFields()->GetItem((long)0).Value;///取得第1列的值,從0開始計數,
strid = (TCHAR*)(_bstr_t)vID //轉換為字符串

vname = m_pRecordset->GetFields()->GetItem( (long)0).name;//取得第一列屬性名
//以直接給出列的名稱,如下一行
vUsername = m_pRecordset->GetCollect("username");///取得username字段的值

m_pRecordset->MoveNext();///移到下一條記錄
}
m_pRecordset->GetFields()->Count//獲得一條記錄的字段數

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("haiyan"));
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();///保存到庫中

在這說明一下:

在我的一個.NET數據庫連接程序中,出現一個問題,每次初始化打開數據集時程序報錯說"數據庫打開錯誤,無效指針",讓我郁悶好幾個小時,后來發現,當我在創建數據庫連接對象前加入函數CoInitialize(NULL)后,錯誤解決,源碼如下:

CoInitialize(NULL);
hr=m_pConnection.CreateInstance(_uuidof(Connection));

MSDC說明如下:

You need to initialize the COM library on an apartment before you call any of the

library functions except CoGetMalloc,to get a pointer to the standard allocator,

and the memory allocation functions

(轉)

為了取得結果記錄集,我們定義一個指向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, nullnullnullnullnullnullnullnullWashingtonnullnullnullnullnullnullnullnull,25,nullnullnullnullnullnullnullnull1970/1/1nullnullnullnullnullnullnullnull)",&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變量 
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對象在進行存儲過程的調用中能真正體現它的作用。下次我們將詳細介

 

 

 

_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 CursorTypeEnum CursorType,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 * FROM Employees”,

_variant_t((IDispatch*)m_pConnection,true),

adOpenStatic,

adLockOptimistic,

adCmdText);

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

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

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

使用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;Data Source=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 EmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERE City='London'",

_variant_t((IDispatch*)m_pConnection,true),

adOpenStatic,

adLockOptimistic,

adCmdText);

}

catch(_com_error &e)

{

AfxMessageBox(e.Description());

}

_variant_t vEmployeeID,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;Data Source=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 EmployeeID,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;Data Source=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 * FROM Employees",

_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/1993 12:00:00"));

m_pRecordset->PutCollect("City",_variant_t("New York"));

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;Data Source=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 * FROM Employees",

_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);

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;

 


免責聲明!

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



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