VC++中通过ADO中的_RecordsetPtr操作数据库:增删改查

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, 悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制

         adLockOptimistic = 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指针通过记录集操作数据库

  1. 打开VC++6.0,新建一个基于对话框的工程RecordsetPtr。在对话框IDD_RECORDSETPTR_DIALOG中进行编辑:
  2. 使用三个GroupBox分成四个部分,第一部分演示如何读取数据库数据;第二部分演示如何修改数据库;第三部分演示如何向数据库中插入数据;第四部分演示如何删除数据库中的数据。
  3. 使用ClassWizard给列表框IDC_LIST1创建CListBox变量m_list1:
  4. 双击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("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_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("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;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 * 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/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 * FROM Employees",

                            _variant_t((IDispatch*)m_pConnection, true),

                            adOpenStatic,

                            adLockOptimistic,

                            adCmdText);

         }

         catch (_com_error &e)

         {

                   AfxMessageBox(e.Description());

         }

         try

         {

                   m_pRecordset->MoveFirst();

                   m_pRecordset->Move(9); //假设删除第10条记录

                   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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/620493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Center审计策略表安装和策略添加(事务)——(Linux/Windows版本)

本博客主要讲述Center的审计策略表安装和策略添加 使用事务添加 1、开启事务 my->StartTransaction(); 2、编写sql语句 //清除原来数据,防止数据污染my->Query("DROP TABLE IF EXISTS t_strategy");string sql "CREATE TABLE t_strategy (…

世微AP630X地摊灯 手电筒方案 可充电多功能LED灯

1,信息来源:深圳市世微半导体有限公司 Augus 2,产品的特性有: 全集成单芯片控制 5 照明循环模式可选 0.5A/1A 固定充电电流可选 内置 MOS 1.8A 驱动电流 可外置 MOS 驱动更大电流 充电指示/低电提示/短路提示 3A 手电筒过流保护? 预设 4.22V 电…

云原生分布式多模架构:华为云多模数据库 GeminiDB 架构与应用实践

文章目录 前言一、GeminiDB 总体介绍1.1、华为云数据库全景图1.2、GeminiDB 发展历程1.3、GeminiDB 全球分布情况 二、GeminiDB 云原生架构2.1、核心设计:存算分离&多模扩展2.2、存算分离&多模扩展核心优势2.3、高可用:秒级故障接管2.4、弹性扩展…

Sonar Qube基本使用

中文化 Sonar Qube的使用方式很多,Maven可以整合,也可以采用sonar-scanner的方式,再查看Sonar Qube的检测效果 Sonar-scanner实现代码检测 下载Sonar-scanner:https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/…

索引的概述和使用

1、概述 索引占用存储空间,并不是越多越好,太多的索引会影响系统性能 索引分类 聚集索引: 逻辑顺序和物理顺序是一致的(表中行数的位置决定了该行在内存中存储的位置),因此效率优先于非聚集索引&#xff…

强化学习应用(六):基于Q-learning的无人机物流路径规划研究(提供Python代码)

一、Q-learning简介 Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个价值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的…

【数据库系统概论】期末复习5

系列文章 期末复习1 期末复习2 期末复习3 期末复习4 系列文章试述数据库设计过程。数据字典的内容和作用是什么?登记日志文件时为什么必须先写日志文件,后写数据库?数据库中为什么要进行数据库恢复?数据库恢复能够保证事务的哪些…

Python: network:sip: pyVoIP;sip测试工具

今天向大家推荐一个开源项目,这个是python实现的一个VoIP的终端模拟器。看着就是一个非常好的通信测试软件。python实现,可以批量化(部分模拟sipp功能)实现通信压力测试,满足一定的需求。需要注意的是可能需要自己在这…

【深度学习】Anaconda3 + PyCharm 的环境配置 3:GitHub 项目运行前的环境配置

前言 文章性质:实操记录 💻 主要内容:主要记录了运行 GitHub 项目前的环境配置过程,包括创建并激活新的虚拟环境、安装 torch 和 torchvision,在 PyCharm 中使用新建的虚拟环境,根据项目源代码提供的 requi…

androidkiller的两种异常情况

第一种反编译时异常: Exception in thread “main” org.jf.dexlib2.dexbacked.DexBackedDexFile$NotADexFile: Not a valid dex magic value: cf 77 4c c7 9b 21 01 修改方法: 编辑 AndroidKiller 的 bin/apktool 目录下有一个 apktool.bat 文件 修改成…

AI智能创作软件,颠覆你的写作体验

你是否想过,有一天,文字创作不再受限于人的思维和表达能力?AI智能文章创作就是这样一个神奇的存在。它运用先进的自然语言处理技术,通过对大量数据的深度学习,根据需要自动生成文章。你只需输入关键词或主题&#xff0…

我们做了个写论文解读的agent

已经2024年了,该出现一个论文解读AI Agent了。 尽管我们公司的主营业务不是做这块的,但,我们还是顺手做了这样一个agent,因为——我们公司的算法同学也需要刷论文啊喂, 而且我们也经常人工写论文解读嘛,所…

电商几乎每一次的调整,几乎都围绕着AI展开

在那个马云依然还掌舵着阿里这艘大船的年月里,因其天马行空的想法,在很多时候总是被冠以「外星人」的名头。 站在今天来看,所谓的「外星人」,或许更多地和当下风靡的「AI」有很多相似之处吧。 他,能洞察商业的内在规…

MySQL面试题 | 05.精选MySQL面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

vue3中的watch 和 watchEffect

1、watch watch第一个参数就是监视目标,第二个参数是一个回调函数。里面有两个参数,分别是目标的新值以及旧值。第三个参数就是用来配置深度监视以及立即监听等。const count ref(0);setTimeout(() > {count.value; }, 1000);watch(count, (newVal, …

VMware 安装及创建一个 CentOS Stream 的详细指南

文章目录 1. 简介2. 下载和安装1)通过官网安装2)通过电脑管家安装 3. 下载操作系统镜像包4. 创建虚拟机结语 1. 简介 在过去,服务器通常是运行单一操作系统和应用程序的物理设备。这就导致了硬件资源浪费和管理复杂性的增加。为了解决这些问…

[Beego]1.Beego简介以及beego环境搭建,bee脚手架的使用,创建,运行项目

一.Beego介绍 Beego是一个开源的基于Golang的MVC框架,主要用于Golang Web开发,Beego可以用来快速开发API、Web、后端服务等各种应用。 Golang 的Web开发框架有很多,从 github star 数量来看Gin>Beego>lris>Echo>Revel>Buffalo 目前国内用的比较多的就…

Web前端篇——el-date-picker日期弹出框大小的修改

通常情况下el-date-picker日期弹出框的大小我们很少去改到它,但是如果某些特定情况下需要我们改动它的话,可以按以下步骤实现: 1.第一步,定义一个style样式 .DateStyle{transform-origin 0 0 !important; } 2.第二步&#xff0…

mysql从入门到放弃之数据库体系结构与管理

文章目录 前言一、体系结构1、mysql c/s结构介绍2、mysql实例组成3、mysqld程序运行原理3.1、mysqld守护进程结构3.2、 引入sql语句结构化的查询语言3.3、探索一条SQL语句的执行过程 二、mysql逻辑存储结构三、mysql物理存储结构3.1、innodb存储引擎的段、区、页之间的关系 四、…

回顾我的2023年

目录 年度回顾 1.1 回顾2023 1.1.1 写博客的初心 1.1.2 写博客的感悟 1.2 2024年的规划 1.2.1 更新内容 1.2.2 更新频率 1.2.3 对自我的期望 年度回顾 1.1 回顾2023 1.1.1 写博客的初心 2023年对我来说,是平凡的一年,也是特别的一年。在2023年…