转自: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. _variant_t vEmployeeID,vFirstName,vLastName;
  27. try
  28. {
  29. while(!m_pRecordset->adoEOF)
  30. {
  31. vEmployeeID=m_pRecordset->GetCollect(_variant_t((long)0));
  32. //取得第1列的值,从0开始计数,你也可以直接列出列的名称,如下一行
  33. vFirstName=m_pRecordset->GetCollect("FirstName");
  34. vLastName=m_pRecordset->GetCollect("LastName");
  35. CString strtemp;
  36. if(vEmployeeID.vt!=VT_NULL)
  37. {
  38. strtemp.Format("%d",vEmployeeID.lVal);
  39. }
  40. if(vFirstName.vt!=VT_NULL)
  41. {
  42. strtemp+=" ";
  43. strtemp+=(LPCTSTR)(_bstr_t)vFirstName;
  44. }
  45. if(vLastName.vt!=VT_NULL)
  46. {
  47. strtemp+=" ";
  48. strtemp+=(LPCTSTR)(_bstr_t)vLastName;
  49. }
  50. m_list1.AddString(strtemp);
  51. m_list1.AddString("/n");
  52. m_pRecordset->MoveNext();
  53. }
  54. }
  55. catch(_com_error &e)
  56. {
  57. AfxMessageBox(e.Description());
  58. }
  59. //释放资源
  60. m_pRecordset->Close();
  61. m_pRecordset=NULL;
  62. m_pConnection->Close();
  63. m_pConnection=NULL;
  64. }

该段代码演示了如何读取数据库表内的数据。其原理是如果没有遇到表结束标志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. m_pRecordset->Update();
  24. }
  25. catch(_com_error* e)
  26. {
  27. AfxMessageBox(e->ErrorMessage());
  28. }
  29. <span style="white-space:pre">  </span>...
  30. }

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

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

  • {
  • <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. m_pRecordset->Update();
  22. }
  23. catch(_com_error *e)
  24. {
  25. AfxMessageBox(e->ErrorMessage());
  26. }
  27. ...
  28. }

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

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

ADO接口之_RecordsetPtr的更多相关文章

  1. ADO接口简介

    源地址:http://blog.csdn.net/xiaobai1593/article/details/7449151 参考: 1. 百度文库:http://wenku.baidu.com/view ...

  2. ADO接口

    转自百度文库 ADO中最重要的对象有三个:Connection.Recordset和Command,分别表示连接对象.记录集对象和命令对象. 三个对象对应的智能指针分别是:_ConnectionPtr ...

  3. 第三次上机,ADO接口的使用

    <html> <head> <title>Reg</title> </head> <body><center> &l ...

  4. VC++ ADO相关

    <VC对ADO的操作> ADO概述: ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口. ADO 使您能够编写应用程序以通过 ...

  5. 智能指针 ADO数据库连接

    ADO库包含三个基本接口:_ConnectionPtr接口._CommandPtr接口和_RecordsetPtr接口._ConnectionPtr接口返回一个记录集或一个空指针.通常使用它来创建一个 ...

  6. 读书笔记——数据库的ADO开发总结

    基本上是对 ADO+开发指南.pdf 的摘抄和总结,以及个人心得. 文章末尾有<ADO+开发指南.pdf>的资源下载,附带个人批注. --------------------------- ...

  7. VC操作ADO的基本策略

    一.ADO概述 ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口.ADO 使您能够编写应用程序以通过 OLE. DB 提供者访问和操作数据 ...

  8. ADO数据库链接

    一.数据库操作准备 // --------------------------------------------------------------------------------------- ...

  9. MFC中使用ADO方式连接数据库

    文章转自:http://blog.sina.com.cn/s/blog_a43aba5601014z8h.html 一.数据库操作准备 1.导入ADO动态链接库 在工程的stdafx.h中加入如下语句 ...

随机推荐

  1. PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载 && Linux下的ZipArchive配置开启压缩 &&搞个鸡巴毛,写少了个‘/’号,浪费了一天

    PHP ZipArchive 是PHP自带的扩展类,可以轻松实现ZIP文件的压缩和解压,使用前首先要确保PHP ZIP 扩展已经开启,具体开启方法就不说了,不同的平台开启PHP扩增的方法网上都有,如有 ...

  2. HDU-5222 Exploration(拓扑排序)

    一.题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5222 二.题意 给一个无向边+有向边的混合图,其中每条边只能使用一次,问图中是否存在环. 三.思路 ...

  3. pythonNet08

    线程通信 通信方法:多个线程共用进程空间,所以进程的全局变量对进程内线程均可见.线程往往使用全局变量进行通信 注意事项:线程间使用全局变量进行通信,全局变量为共享资源,往往需要同步互斥机制 线程的同步 ...

  4. js实现的快速排序

    快速排序是一种平均性能非常优秀的排序算法,在很多场合都会应用到他. 了解快速排序于对开放高效率的软件有很重要的作用. 但是有不少的书本讲得并不是很清楚,而且不同的教材的实现方式也不尽相同, 我这里将最 ...

  5. J2EE Filter中修改request内容

    最近在做一个微信相关的网站,很多地方涉及到微信表情的输入,导致内容无法插入到数据库,虽然有用到一个表情过滤的工具类,但是需要过滤的地方比较多,于是想到在过滤器中过滤用户请求的内容. request这个 ...

  6. java后端时间处理工具类,返回 "XXX 前" 的字符串

    转自:https://www.cnblogs.com/devise/p/9974672.html 我们经常会遇到显示 "某个之间之前" 的需求(比如各种社交软件,在回复消息时,显示 ...

  7. IOS 证书失效

    IOS 证书失效,能选择ppf,选择不了证书. [Error] No certificate found in provisioning profile "aee9b804-bc71-4ce ...

  8. 按键精灵对VBS的支持

    VBSBegin…VBSEnd(VBS块)格式:VBSBegin...VBSEnd用途:可以在VBS块的区域内随意的书写VBS语法指令. 更多说明:由于彻底的转向VBS语言,会导致goto语句不能被兼 ...

  9. 44. Wildcard Matching (String; DP, Back-Track)

    Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...

  10. UNITY地图寻路及服务器解决方案

    多边形寻路算法简单介绍 http://liweizhaolili.lofter.com/post/1cc70144_86a939e UNITY3D MMO服务器寻路 http://www.pathen ...