zoukankan      html  css  js  c++  java
  • ADO接口之_RecordsetPtr

    转自:http://hi.baidu.com/%CE%D2%B6%CF%C1%CB%CB%BC%C4%EE/blog/item/e057c526c6af6c29c995596e.html

    _RecordsetPtr智能指针,它是专门为通过记录集操作数据库而设立的指针,通过该接口可以对数据库的表内的记录、字段等进行各种操作。

    要搞清楚:数据库和ADO的记录集是两个不同的概念,是存在于不同物理位置的两个存储空间。

                       记录集相当于是实际数据的一份拷贝。 正因为记录集是相对脱离数据库而存在的, 所以才存在后面将要介绍的Open方法中涉及的光标类型和锁定类型这两个问题。

    _RecordsetPtr接口的使用方法

    1> 创建记录集对象

    1. _ConnectionPtr m_pRecordset;  
    2. m_pRecordset.CreateInstance(__uuidof(Recorset));  

    创建记录集对象,只是为它分配内存空间,记录集中不含任何数据。

    2> 打开记录集

    记录集对象是用来获得数据库中的数据并对其操作的,所以还要打开记录集,从数据库中取得数据记录。可有多种方法打开记录集,如使用_CommondPt::.Execute()来返回一个记录集,或是用_Recordset::Open()方法来打开一个记录集;

    下面只介绍Open()方法:

    函数原型为:

    HRESULT Recordset::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锁定类型,它可以是以下值之一,请看如下枚举结构

    1. enum LockTypeEnum  
    2. {  
    3.     adLockUnspecified=-1,  
    4.     //未指定  
    5.     adLockReadOnly=1,  
    6.     //只读记录集,默认值。无法更改数据。  
    7.     adLockPessimistic=2,  
    8.     //悲观锁定方式。只有在调用Update方法时才锁定记录。这是最安全的锁定机制  
    9.     adLockOptimistc=3,  
    10.     //乐观锁定方式,只有在你调用Update方法时才锁定记录。  
    11.     adLockBatchOptimistic=4   
    12.     //乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。  
    13. }  

    关于光标和锁定类型,对于一般用户,建议您只作简单了解,后面将进一步进行解说。

    Options可以取如下值之一:

    adCmdText: 表明CommandText是文本命令。

    adCmdTable:表明CommandText是一个表名。

    adCmdProc:表明CommandText是一个存储过程。

    adCmdUnknown:未知。

    例如:假设m_pConnection是我们已经建立好的连接,我们使用_RecordsetPtr接口的Open方法打开Employees表的记录集的语句如下:

    1. m_pRecordset->Open("SELECT * FROM Employees", _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText);  

    3> 指针的移动

    移动记录指针可以通过MoveFirst()方法移动到第一条记录,MoveLast()方法移动到最后一条记录,MovePrevious()方 法移动到当前记录的前一条记录,MoveNext()方法移动到当前记录的下一条记录。也可以使用Move(记录号)移动记录指针到需要位置。

    注意:Move()方法是相对于当前记录来移动指针位置的。正值向后移动,负值向前移动。如Move(3),当前记录是3时,它将从记录3开始往后再移动3条记录位置。

    两个_RecordsetPtr属性:

    BOF  属性表示记录集第一条记录之前的游标,用来判断记录集是否为空

    EOF(通常会rename为adoEOF) 属性表示记录集最后一条记录之后的游标,用来判断是否结束

    4> 数据的读取

    GetCollect(字段名)来获取当前记录指针所指的字段值

    返回值的类型为:_variant_t

    5> 数据的更新

    用PutCollect(字段名,值)将新值写入,并Update()更新到数据库

    6> 插入记录

    先移动记录指针到要插入的位置,用AddNew()插入一条记录,然后用PutCollect(字段名,值)写入值,最后用Update()更新到数据库;

    7> 删除记录

    删除单条记录:先移动记录指针到合适的位置,然后用Delete()方法删除它(取参数adAffectCurrent,表示操作只影响当前的记录),并用Update()来更新数据库;

    8> 关闭记录集

    直接用Close()方法关闭记录集并赋予其空值。代码如下:

    m_pRecordset->Close();

    m_pRecordset=NULL;

    类似于_ConnectionPtr的关闭方法;

    示例:

    例程RecordsetPtr演示使用_RecordsetPtr指针通过记录集操作数据库。

    打开VC++ 6.0,新建一个基于对话框的工程RecordsetPtr。在对话框IDD_RECORDSETPTR_DIALOG中进行编辑:

    使用三个Group Box分成四个部分,第一部分演示如何读取数据库数据;第二部分演示如何修改数据库;第三部分演示如何向数据库中插入数据;第四部分演示如何删除数据库中的数据。

    使用ClassWizard给列表框IDC_LIST1创建CListBox变量m_list1:

    双击IDC_BTN_READREC按钮,并编辑OnBtnReadrec()函数如下:

    1. void CRecordsetPtrDlg::OnBtnReadrec()  
    2. {  
    3.     _ConnectionPtr m_pConnection;  
    4.     _RecordsetPtr m_pRecordset;  
    5.     try  
    6.     {  
    7.         m_pConnection.CreateInstance(__uuidof(Connection));  
    8.         m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Northwind.mdb","","",adModeUnknown);  
    9.     }  
    10.     catch(_com_error e)  
    11.     {  
    12.         CString errormessage;  
    13.         errormessage.Format("连接数据库失败!/r错误信息:%s",e.ErrorMessage());  
    14.         AfxMessageBox(errormessage);  
    15.         return;  
    16.     }  
    17.     try  
    18.     {  
    19.         m_pRecordset.CreateInstance("ADODB.Recordset");  
    20.         m_pRecordset->Open("SELECT EmployeeID,FirstName,LastName FROM Employees WHERE City='London'", _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText);  
    21.     }  
    22.     catch(_com_error &e)  
    23.     {  
    24.         AfxMessageBox(e.Description());  
    25.     }  
    26.   
    27.     _variant_t vEmployeeID,vFirstName,vLastName;  
    28.     try  
    29.     {  
    30.         while(!m_pRecordset->adoEOF)  
    31.         {  
    32.             vEmployeeID=m_pRecordset->GetCollect(_variant_t((long)0));  
    33.             //取得第1列的值,从0开始计数,你也可以直接列出列的名称,如下一行  
    34.             vFirstName=m_pRecordset->GetCollect("FirstName");  
    35.             vLastName=m_pRecordset->GetCollect("LastName");  
    36.   
    37.             CString strtemp;  
    38.             if(vEmployeeID.vt!=VT_NULL)  
    39.             {  
    40.                 strtemp.Format("%d",vEmployeeID.lVal);  
    41.             }  
    42.             if(vFirstName.vt!=VT_NULL)  
    43.             {  
    44.                 strtemp+=" ";  
    45.                 strtemp+=(LPCTSTR)(_bstr_t)vFirstName;  
    46.             }  
    47.             if(vLastName.vt!=VT_NULL)  
    48.             {  
    49.                 strtemp+=" ";  
    50.                 strtemp+=(LPCTSTR)(_bstr_t)vLastName;  
    51.             }  
    52.           
    53.             m_list1.AddString(strtemp);  
    54.             m_list1.AddString("/n");  
    55.             m_pRecordset->MoveNext();  
    56.         }  
    57.     }  
    58.     catch(_com_error &e)  
    59.     {  
    60.         AfxMessageBox(e.Description());  
    61.     }  
    62.   
    63.     //释放资源  
    64.     m_pRecordset->Close();  
    65.     m_pRecordset=NULL;  
    66.     m_pConnection->Close();  
    67.     m_pConnection=NULL;  
    68. }  

    该段代码演示了如何读取数据库表内的数据。其原理是如果没有遇到表结束标志adoEOF,则用GetCollect(字段名)来获取当前记录指针所指的字段值,然后再用MoveNext()方法移动到下一条记录位置。

    双击IDC_BTN_CHANGE按钮,并编辑OnBtnChange()函数如下:

    1. void CRecordsetPtrDlg::OnBtnChange()  
    2. {  
    3. <span style="white-space:pre">  </span>...  
    4.     try  
    5.     {  
    6.         m_pRecordset.CreateInstance("ADODB.Recordset");  
    7.         m_pRecordset->Open("SELECT EmployeeID,FirstName,LastName FROM Employees WHERE (City='London') AND (EmployeeID=6)",  
    8.         _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText);  
    9.     }  
    10.     catch(_com_error &e)  
    11.     {  
    12.         AfxMessageBox(e.Description());  
    13.     }  
    14.     try  
    15.     {  
    16.         while(!m_pRecordset->adoEOF)  
    17.         {  
    18.             //更改记录值  
    19.             m_pRecordset->PutCollect("LastName",_variant_t("Jackson"));  
    20.             m_pRecordset->MoveNext();  
    21.         }  
    22.       
    23.         //刷新到硬盘中  
    24.         m_pRecordset->Update();  
    25.     }  
    26.     catch(_com_error* e)  
    27.     {  
    28.         AfxMessageBox(e->ErrorMessage());  
    29.     }  
    30. <span style="white-space:pre">  </span>...  
    31. }  

    该段代码演示了如何修改记录中的字段值:

    将记录指针移动到要修改记录的位置处,直接

    • {  
    • <span style="white-space:pre">  </span>...  
    •     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"));  
    •     }  
    •     catch(_com_error *e)  
    •     {  
    •         AfxMessageBox(e->ErrorMessage());  
    •     }  
    •       
    •     //更新到外存  
    •     m_pRecordset->Update();  
    •     ...  
    • }  

    该段代码演示如何插入记录:

    先用AddNew()方法新增一个空记录,再用PutCollect(字段名,值)输入每个字段的值,最后用Update()更新到数据库即可。

    双击IDC_BTN_DELETE按钮,并编辑OnBtnDelete()函数如下:

    1. void CRecordsetPtrDlg::OnBtnDelete()  
    2. {  
    3.     ...  
    4.     try  
    5.     {  
    6.         m_pRecordset.CreateInstance("ADODB.Recordset");  
    7.         m_pRecordset->Open("SELECT * FROM Employees", _variant_t((IDispatch*)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText);  
    8.     }  
    9.     catch(_com_error &e)  
    10.     {  
    11.         AfxMessageBox(e.Description());  
    12.     }  
    13.     try  
    14.     {  
    15.         //假设删除第10条记录  
    16.         m_pRecordset->MoveFirst();  
    17.         m_pRecordset->Move(9);  
    18.         //参数adAffectCurrent为删除当前记录  
    19.         m_pRecordset->Delete(<span style="background-color: rgb(204, 204, 204);">adAffectCurrent</span>);  
    20.   
    21.         //更新到数据库中  
    22.         m_pRecordset->Update();  
    23.     }  
    24.     catch(_com_error *e)  
    25.     {  
    26.         AfxMessageBox(e->ErrorMessage());  
    27.     }  
    28.     ...  
    29. }  

    该段代码演示了如何删除记录:

    先将记录指针移动到要删除的记录的位置,直接用Delete()方法删除它,并用Update()来更新数据库即可。

  • 相关阅读:
    SDUT 2143 图结构练习——最短路径 SPFA模板,方便以后用。。 Anti
    SDUT ACM 1002 Biorhythms 中国剩余定理 Anti
    nyist OJ 119 士兵杀敌(三) RMQ问题 Anti
    SDUT ACM 2157 Greatest Number Anti
    SDUT ACM 2622 最短路径 二维SPFA启蒙题。。 Anti
    二叉索引树 区间信息的维护与查询 Anti
    SDUT ACM 2600 子节点计数 Anti
    UVA 1428 Ping pong 二叉索引树标准用法 Anti
    2010圣诞Google首页效果
    Object
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/3857346.html
Copyright © 2011-2022 走看看