search
HomeDatabaseMysql TutorialVisual c++ 6.0 ADO access

ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。 _ConnectionPtr接口返回一个记录集或一个空指针。 通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。 使用_ConnectionPtr接口返回一个记

ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。
_ConnectionPtr接口返回一个记录集或一个空指针。
通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。
通常同Cdatabase一样,使用它创建一个数据连接,然后使用其它对象执行数据输入输出操作。
_CommandPtr接口返回一个记录集。
它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。
在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。
如果你只执行一次或几次数据访问操作,后者是比较好的选择。
但如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,
然后使用_CommandPtr接口执行存储过程和SQL语句。
_RecordsetPtr是一个记录集对象。
与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等
。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,
可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。
如果你要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口
,然后使用_RecordsetPtr执行存储过程和SQL语句。

(1)初始化COM库,引入ADO库定义文件
(2)用Connection对象连接数据库
(3)利用建立好的连接,通过Connection、Command对象执行SQL命令,或利用Recordset对象取得结果记
录集进行查询、处理。
(4)使用完毕后关闭连接释放对象。

我们可以使用AfxOleInit()来初始化COM库,这项工作通常在CWinApp::InitInstance()的重载函数中完
成,请看如下代码:
BOOL CADOTest1App::InitInstance()
{
AfxOleInit();
......
}

我们在stdafx.h中加入如下语句:
#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","adoEOF")
其最终作用同我们熟悉的#include类似,编译的时候系统会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。

首先我们需要添加一个指向Connection对象的指针:
_ConnectionPtr m_pConnection;
BOOL CADOTest1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
try
{
HRESULT hr = m_pConnection.CreateInstance("ADODB.Connection");//创建Connection对象
if(SUCCEEDED(hr))
{
hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb","","",adModeUnknown);//连接数据库
//上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51; }
}
}
catch (_com_error e) //COM错误取得,当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
{
CString strComError;
strComError.Format("错误编号: %08lx/n错误信息: %s/n错误源: %s/n错误描述: %s",
e.Error(), // 错误编号
e.ErrorMessage(), // 错误信息
(LPCSTR) e.Source(), // 错误源
(LPCSTR) e.Description()); // 错误描述
::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION);
}
}
也可以使用UDL文件进行连接。
try
{
m_pConnection.CreateInstance(__uuidof(Connection));
m_pConnection->ConnectionString ="File Name=e.udl";
m_pConnection->Open("","","",NULL);
}
catch(_com_error e)
{....}
◆在这段代码中我们是通过Connection对象的Open方法来进行连接数据库的,下面是该方法的原型
HRESULT Connection15::Open (_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options )
ConnectionString 为连接字串,
UserID 是用户名,
Password 是登陆密码,
Options 是连接选项,用于指定Connection对象对数据的更新许可权,
Options可以是如下几个常量:
adModeUnknown: 缺省。当前的许可权未设置
adModeRead: 只读
adModeWrite: 只写
adModeReadWrite: 可以读写
adModeShareDenyRead: 阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite: 阻止其它Connection对象以写权限打开连接
adModeShareExclusive: 阻止其它Connection对象打开连接
adModeShareDenyNone: 允许其它程序或对象以任何权限建立连接
◆常用的数据库连接方法:
(1)通过JET数据库引擎对ACCESS2000数据库的连接
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C://test.mdb","","",adModeUnknown);
(2)通过DSN数据源对任何支持ODBC的数据库进行连接:
m_pConnection->Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);
//m_pConnection->Open("DSN=test;","","",0); //连接叫作test的ODBC数据源
(3)不通过DSN对SQL SERVER数据库进行连接:
m_pConnection->Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139","","",adModeUnknown);
其中Server是SQL服务器的名称,DATABASE是库的名称
◆先介绍Connection对象中两个有用的属性ConnectionTimeOut与State
ConnectionTimeOut用来设置连接的超时时间,需要在Open之前调用,例如:
m_pConnection->ConnectionTimeout = 5; //设置超时时间为5秒
m_pConnection->Open("Data Source=adotest;","","",adModeUnknown);
State属性指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过
读取这个属性来作相应的处理,例如:
if(m_pConnection->State)
m_pConnection->Close(); //如果已经打开了连接则关闭它
4】
为了取得结果记录集,我们定义一个指向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执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
try
{
_variant_t ra;
m_pConnection->Execute("CREATE TABLE student(Sno INTEGER,Sname TEXT,Ssex TEXT,Sage INTEGER,Sdept TEXT)",&ra,adCmdText);
m_pConnection->Execute("INSERT INTO 学生信息(学号,姓名,年龄,生日) valueS (112105, '程红秀',22,'1982-08-16')",&ra,adCmdText);//往表格里面添加记录
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM 学生信息",&ra,adCmdText); //执行SQL统计命令得到包含记录条数的记录集
_variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)(0)); //取得第一个字段的值放入vCount变量
m_pRecordset->Close();
CString message;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);
}
catch (_com_error e)
{ ...}
◆(2)利用 Command对象 来执行SQL命令
try
{
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
m_pCommand->ActiveConnection = m_pConnection; //关键的一句,将建立的连接赋值给它
m_pCommand->CommandText="INSERT INTO 学生信息(学号,姓名,年龄,生日) valueS (112105, '程红秀',22,'1982-08-16')";
m_pCommand->Execute(NULL,NULL,adCmdText);
m_pCommand->CommandText="SELECT COUNT(*) FROM 学生信息";
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdText);
_variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)0); //取得第一个字段的值
CString str;
str.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(str);
m_pRecordset->Close();
}
catch (_com_error e) {...}
在这段代码中我们只是用Command对象来执行了SELECT查询语句,
Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
◆(3)直接用Recordset对象进行查询取得记录集
例如
m_pRecordset->Open("SELECT * FROM 学生信息",_variant_t((IDispatch *)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
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, //乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
⑤Options请参考本文中对Connection对象的Execute方法的介绍

根据我们刚才通过执行SQL命令建立好的 学生信息 表,它包含四个字段:学号,姓名,年龄,生日
以下的代码实现:打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条
记录,更改其年龄,保存到数据库。
try
{
_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT * FROM 学生信息",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
while(!m_pRecordset->adoEOF)
{
vID = m_pRecordset->GetCollect(_variant_t((long)0)); //取得第1列的值,从0开始计数,你也可以直接给出列的名称,如下一行
vUsername = m_pRecordset->GetCollect("姓名"); //取得姓名字段的值
vOld = m_pRecordset->GetCollect("年龄");
vBirthday = m_pRecordset->GetCollect("生日");
TRACE("id:%d,姓名:%s,年龄:%d,生日:%s/r/n",
vID.lVal,
(LPCTSTR)(_bstr_t)vUsername,
vOld.lVal,
(LPCTSTR)(_bstr_t)vBirthday); //在DEBUG方式下的OUTPUT窗口输出记录集中的记录
m_pRecordset->MoveNext(); //移到下一条记录
}
m_pRecordset->MoveFirst(); //移到首条记录
m_pRecordset->Delete(adAffectCurrent); //删除当前记录
for(int i=0;i{
m_pRecordset->AddNew(); //添加新记录
m_pRecordset->PutCollect("学号",_variant_t((long)(i+10)));
m_pRecordset->PutCollect("姓名",_variant_t("王斌年"));
m_pRecordset->PutCollect("年龄",_variant_t((long)21));
m_pRecordset->PutCollect("生日",_variant_t("1930-3-15"));
}
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst)); //从第一条记录往下移动一条记录,即移动到第二条记录处
m_pRecordset->PutCollect(_variant_t("年龄"),_variant_t((long)45)); //修改其年龄
m_pRecordset->Update(); //保存到库中
} catch (_com_error e){}

记录集或连接都可以用Close方法来关闭
m_pRecordset->Close(); //关闭记录集
m_pConnection->Close(); //关闭连接
在stdafx.h中进行宏定义:
#if !defined CATCH_ERROR
#define CATCH_ERROR /
{ /
CString strComError; /
strComError.Format("错误编号: %08lx/n错误信息: %s/n错误源: %s/n错误描述: %s", /
e.Error(), /
e.ErrorMessage(), /
(LPCSTR) e.Source(), /
(LPCSTR) e.Description()); /
::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION); /
}
#endif
使用方法:
try
{ ...}
catch(_com_error e)
{
CATCH_ERROR;
}

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Windows 11 系统下的五款最佳免费 C++ 编译器推荐Windows 11 系统下的五款最佳免费 C++ 编译器推荐Apr 23, 2023 am 08:52 AM

C++是一种广泛使用的面向对象的计算机编程语言,它支持您与之交互的大多数应用程序和网站。你需要编译器和集成开发环境来开发C++应用程序,既然你在这里,我猜你正在寻找一个。我们将在本文中介绍一些适用于Windows11的C++编译器的主要推荐。许多审查的编译器将主要用于C++,但也有许多通用编译器您可能想尝试。MinGW可以在Windows11上运行吗?在本文中,我们没有将MinGW作为独立编译器进行讨论,但如果讨论了某些IDE中的功能,并且是DevC++编译器的首选

Windows 11 是否提供对 VB6 应用程序的支持?Windows 11 是否提供对 VB6 应用程序的支持?May 30, 2023 am 08:31 AM

Windows11引入了更多macOS风格的UI元素。您将获得重新设计的任务栏,开始菜单位于中心。是的,您可以更改它的位置,但默认情况下,它将放置在中心。控制中心还进行了一些设计调整。在下一次更新中,对Android应用程序的支持也将与重新设计的记事本和媒体播放器一起提供。尽管所有这些功能都使Windows11比Windows10有了不错的升级,但用户的脑海中正在酝酿某些疑虑。有一部分用户和开发人员担心Windows11是否会支持遗留应用程序和技术,无论是否落后。由于V

如何修复 VCRUNTIME140.dll 在 Windows 上丢失错误如何修复 VCRUNTIME140.dll 在 Windows 上丢失错误May 04, 2023 am 08:04 AM

VCRUNTIME140.dllismissing错误是您在Windows上的VisualC++Redistributable文件存在问题。您可以使用本教程解决问题。Windows应用程序和软件需要DLL文件才能运行——没有它们,它们可能会完全停止工作。例如,如果您看到VCRUNTIME140.dllismissing错误,这表明您的PC缺少此文件,从而阻止应用程序启动。这可能是由于应用程序安装不成功。它甚至可以在运行Windows更新后出现。值得庆幸的是,您可以很容易

4 修复 CONCRT140.dll 未找到错误的方法4 修复 CONCRT140.dll 未找到错误的方法Apr 25, 2023 am 09:22 AM

如此多的用户报告说,每当他们尝试运行应用程序时,它都会抛出一条错误消息,指出代码执行无法继续,因为未找到CONCRT140.dll。在打开Adob​​e应用程序、Halo、ForzaHorizo​​n5等时,您可能会遇到找不到CONCRT140.dll。因此,这不是特定于某个应用程序的问题。如果没有安装正确的DLL,应用程序将无法正常工作,因为它们的代码依赖于这些库中编写的代码。在本文中,我们将了解CONCRT140.dll是什么以及它丢失的原因,以及我们如何下载它并修复错误。什么是

修复:Microsoft Visual C++ 2015 Redistributable Setup Failed 错误 0x80240017修复:Microsoft Visual C++ 2015 Redistributable Setup Failed 错误 0x80240017Apr 18, 2023 pm 01:07 PM

MicrosoftVisualC++已成为运行大多数常见应用程序所需的Windows操作系统的组成部分。现在,一些用户最近抱怨他们在尝试安装VisualC++RedistributablePackagesfor2015或MicrosoftVisualStudioRedistributablePackagesfor2013时遇到的问题。根据这些用户的说法,安装程序中途停止并显示“0x80240017-未指定错误”.这次失败的背后可能有很多原因。因此,不要在此

C++编译错误:未定义的引用,该怎么解决?C++编译错误:未定义的引用,该怎么解决?Aug 21, 2023 pm 08:52 PM

C++是一门广受欢迎的编程语言,但是在使用过程中,经常会出现“未定义的引用”这个编译错误,给程序的开发带来了诸多麻烦。本篇文章将从出错原因和解决方法两个方面,探讨“未定义的引用”错误的解决方法。一、出错原因C++编译器在编译一个源文件时,会将它分为两个阶段:编译阶段和链接阶段。编译阶段将源文件中的源码转换为汇编代码,而链接阶段将不同的源文件合并为一个可执行文

C++编译错误:无法为类模板找到实例化,应该怎么解决?C++编译错误:无法为类模板找到实例化,应该怎么解决?Aug 21, 2023 pm 08:33 PM

C++是一门强大的编程语言,它支持使用类模板来实现代码的复用,提高开发效率。但是在使用类模板时,可能会遭遇编译错误,其中一个比较常见的错误是“无法为类模板找到实例化”(error:cannotfindinstantiationofclasstemplate)。本文将介绍这个问题的原因以及如何解决。问题描述在使用类模板时,有时会遇到以下错误信息:e

iostream头文件的作用是什么iostream头文件的作用是什么Mar 25, 2021 pm 03:45 PM

iostream头文件包含了操作输入输出流的方法,比如读取一个文件,以流的方式读取;其作用是:让初学者有一个方便的命令行输入输出试验环境。iostream的设计初衷是提供一个可扩展的类型安全的IO机制。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function