登录注册
上海交通大学论坛 > 数据库 > 浏览当前帖子 手机版 关闭左侧栏
用VC开发数据库(六)*转载*
返回本版】  【发表帖子】  【回复帖子 浏览量  4044      回帖数 0
大汉天子    等级  

楼主 发表于  2011/10/11 10:30:13    编 辑   


6、 使用ADO 
6.1 概述 
ADO是ActiveX数据对象(ActiveX Data Object),这是Microsoft开发数据库应用程序 
的面向对象的新接口。ADO访问数据库是通过访问OLE DB数据提供程序来进行的,提供了 
一种对OLE DB数据提供程序的简单高层访问接口。 
ADO技术简化了OLE DB的操作,OLE DB的程序中使用了大量的COM接口,而ADO封装了这些 
接口。所以,ADO是一种高层的访问技术。 
ADO技术基于通用对象模型(COM),它提供了多种语言的访问技术,同时,由于ADO提供 
了访问自动化接口,所以,ADO可以用描述的脚本语言来访问VBScript,VCScript等。 
  
6.2 在VC中使用ADO 
可以使用VC6提供的ActiveX控件开发应用程序,还可以用ADO对象开发应用程序。使用A 
DO对象开发应用程序可以使程序开发者更容易地控制对数据库的访问,从而产生符合用 
户需求的数据库访问程序。 
使用ADO对象开发应用程序也类似其它技术,需产生与数据源的连接,创建记录等步骤, 
但与其它访问技术不同的是,ADO技术对对象之间的层次和顺序关系要求不是太严格。在 
程序开发过程中,不必选建立连接,然后才能产生记录对象等。可以在使用记录的地方 
直接使用记录对象,在创建记录对象的同时,程序自动建立了与数据源的连接。这种模 
型有力的简化了程序设计,增强了程序的灵活性。下面讲述使用ADO对象进行程序设计的 
方法。 
6.21 引入ADO库文件 
使用ADO前必须在工程的stdafx.h文件里用直接引入符号#import引入ADO库文件,以使 
编译器能正确编译。代码如下所示: 
#define INITGUID 
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace  
rename("EOF","EndOfFile") 
#include "icrsint.h" 
这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免冲突,将EOF改 
名为EndOfFile。 
6.22 初始化ADO环境 
在使用ADO对象之前必须先初始化COM环境。初始化COM环境可以用以下代码完成: 
::CoInitialize(NULL); 
在初始化COM环境后,就可以使用ADO对象了,如果在程序前面没有添加此代码,将会产 
生COM错误。 
在使用完ADO对象后,需要用以下的代码将初始化的对象释放: 
::CoUninitialize(); 
此函数清除了为ADO对象准备的COM环境。 
6.23 接口简介 
ADO库包含三个基本接口
__ConnectionPtr接口、 
__CommandPtr接口、 
__RecordsetPtr接口, 
  
__ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或 
执行一条不返回任何结果的SQL语句,如一个存储过程。用__ConnectionPtr接口返回一 
个记录集不是一个好的使用方法。通常同CDatabase一样,使用它创建一个数据连接,然 
后使用其它对象执行数据输入输出操作。 
  
__CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储 
过程和SQL语句。在使用__CommandPtr接口时,可以利用全局__ConnectionPtr接口,也 
可以在__CommandPtr接口里直接使用连接串。如果只执行一次或几次数据访问操作,后 
者是比较好的选择。但如果要频繁访问数据库,并要返回很多记录集,那么,应该使用 
全局__ConnectionPtr接口创建一个数据连接,然后使用__CommandPtr接口执行存储过程 
和SQL语句。 
  
__RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控 
制功能,如记录锁定,游标控制等。同__CommandPtr接口一样,它不一定要使用一个已 
经创建的数据连接,可以用一个连接串代替连接指针赋给__RecordsetPtr的connection 
成员变量,让它自己创建数据连接。如果要使用多个记录集,最好的方法是同Command对 
象一样使用已经创建了数据连接的全局—ConnectionPtr接口,然后使用__Recordse7tP 
tr执行存储过程和SQL语句。 
6、24 使用ADO访问数据库 
__ConnectionPtr是一个连接接口,首先创建一个__ConnectionPtr接口实例,接着指向 
并打开一个ODBC数据源或OLE DB数据提供者(Provider)。以下代码分别创建一个基于DS 
N和非DSN的数据连接。 
  
  //使用__ConnectionPtr(基于DSN) 
  __ConnectionPtr MyDb; 
  MyDb.CreateInstance(__uuidof(Connection)); 
  MyDb-〉Open("DSN=samp;UID=admin;PWD=admin","","",-1); 
  //使用—ConnectionPtr (基于非DSN) 
  __ConnectionPtr MyDb; 
  MyDb.CreateInstance(__uuidof(Connection)); 
MyDb.Open("Provider=SQLOLEDB;SERVER=server;DATABASE=samp;UID=admin;PWD=admin 
","","",-1); 
  
//使用__RecordsetPtr执行SQL语句 
  __RecordsetPtr MySet; 
  MySet.CreateInstance(__uuidof(Recordset)); 
MySet-〉Open("SELECT * FROM some__table",  MyDb.GetInterfacePtr(),adOpe 
nDynamic,adLockOptimistic,adCmdText); 
现在我们已经有了一个数据连接和一个记录集,接下来就可以使用数据了。从以下代码 
可以看到,使用ADO的__RecordsetPtr接口,就不需要像DAO那样频繁地使用大而复杂的 
数据结构VARIANT,并强制转换各种数据类型了,这也是ADO的优点之一。假定程序有一 
个名称为m__List的ListBox控件,下面代码我们用__RecordsetPtr接口获取记录集数据 
并填充这个ListBox控件: 
__variant__t Holder 
  try{while(!MySet-〉adoEOF) 
  { Holder = MySet-〉GetCollect("FIELD__1"); 
  if(Holder.vt!=VT__NULL) 
  m__List.AddString((char)__bstr__t(Holder)); 
  MySet-〉MoveNext();} } 
  catch(__com__error  e) 
  { CString Error = e-〉ErrorMessage(); 
   AfxMessageBox(e-〉ErrorMessage()); 
  } catch(...) 
  { MessageBox("ADO发生错误!");} 
  
必须始终在代码中用try和catch来捕获ADO错误,否则ADO错误会使你的应用程序崩溃。当 
ADO发生运行错误时(如数据库不存在),OLE DB数据提供者将自动创建一个__com__erro 
r对象,并将有关错误信息填充到这个对象的成员变量。 
  
6.25 类型转换 
由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,因此CStri 
ng 类和COM对象是不兼容的,我们需要一组API来转换COM对象和C++类型的数据。__v 
atiant__t和__bstr__t就是这样两种对象。它们提供了通用的方法转换COM对象和C++ 
类型的数据。 
6.3 在VB中使用ADO 
ADO 提供执行以下操作的方式: 
1、连接到数据源。同时,可确定对数据源的所有更改是否已成功或没有发生。 
2、指定访问数据源的命令,同时可带变量参数,或优化执行。 
3、执行命令。 
3、如果这个命令使数据按表中的行的形式返回,则将这些行存储在易于检查、操作或更 
改的缓存中。 
4、适当情况下,可使用缓存行的更改内容来更新数据源。 
5、提供常规方法检测错误(通常由建立连接或执行命令造成)。 
在典型情况下,需要在编程模型中采用所有这些步骤。但是,由于 ADO 有很强的灵活性 
,所以最后只需执行部分模块就能做一些有用的工作。 
  
以下元素是 ADO 编程模型中的关键部分: 
6.31 连接 
通过“连接”可从应用程序访问数据源,连接是交换数据所必需的环境。对象模型使用 
 Connection 对象使连接概念得以具体化。 
“事务”用于界定在连接过程中发生的一系列数据访问操作的开始和结束。ADO 可明确 
事务中的操作造成的对数据源的更改或者成功发生,或者根本没有发生。如果取消事务 
或它的一个操作失败,则最终的结果将仿佛是事务中的操作均未发生,数据源将会保持 
事务开始以前的状态。对象模型无法清楚地体现出事务的概念,而是用一组 Connectio 
n 对象方法来表示。ADO 从 OLE DB 提供者访问数据和服务。Connection 对象用于指定 
专门的提供者和任意参数。 
  
6.32 命令 
通过已建立的连接发出的“命令”可以某种方式来操作数据源。一般情况下,命令可以 
在数据源中添加、删除或更新数据,或者在表中以行的格式检索数据。对象模型用 Com 
mand 对象来体现命令概念。使用 Command 对象可使 ADO 优化命令的执行。 
参数 
通常,命令需要的变量部分即“参数”可以在命令发布之前进行更改。例如,可重复发 
出相同的数据检索命令,但每一次均可更改指定的检索信息。 
参数对与函数活动相同的可执行命令非常有用,这样就可知道命令是做什么的,但不必 
知道它如何工作。例如,可发出一项银行过户命令,从一方借出贷给另一方。可将要过 
户的款额设置为参数。 
对象模型用 Parameter 对象来体现参数概念。 
6.33 记录集 
如果命令是在表中按信息行返回数据的查询(行返回查询),则这些行将会存储在本地 
。 
对象模型将该存储体现为 Recordset 对象。但是,不存在仅代表单独一个 Recordset  
行的对象。 
记录集是在行中检查和修改数据最主要的方法。 
6.34 字段 
一个记录集行包含一个或多个“字段”。如果将记录集看作二维网格,字段将排列构成 
“列”。每一字段(列)都分别包含有名称、数据类型和值的属性,正是在该值中包含 
了来自数据源的真实数据。 
对象模型以 Field 对象体现字段。 
要修改数据源中的数据,可在记录集行中修改 Field 对象的值,对记录集的更改最终被 
传送给数据源。作为选项,Connection 对象的事务管理方法能够可靠地保证更改要么全 
部成功,要么全部失败。 
6.35 错误 
错误随时可在应用程序中发生,通常是由于无法建立连接、执行命令或对某些状态(例 
如,试图使用没有初始化的记录集)的对象进行操作。 
对象模型以 Error 对象体现错误。 
任意给定的错误都会产生一个或多个 Error 对象,随后产生的错误将会放弃先前的 Er 
ror 对象组。 
6.36 属性 
每个 ADO 对象都有一组唯一的“属性”来描述或控制对象的行为。 
属性有内置和动态两种类型。内置属性是 ADO 对象的一部分并且随时可用。动态属性则 
由特别的数据提供者添加到 ADO 对象的属性集合中,仅在提供者被使用时才能存在。 
  
对象模型以 Property 对象体现属性。 
6.37 集合 
ADO 提供“集合”,这是一种可方便地包含□□特殊类型对象的对象类型。使用集合方 
法可按名称(文本字符串)或序号(整型数)对集合中的对象进行检索。 
ADO 提供四种类型的集合: 
Connection 对象具有 Errors 集合,包含为响应与数据源有关的单一错误而创建的所有 
 Error 对象。 
Command 对象具有 Parameters 集合,包含应用于 Command 对象的所有 Parameter 对 
象。 
Recordset 对象具有 Fields 集合,包含所有定义 Recordset 对象列的 Field 对象。 

此外,Connection、Command、Recordset 和 Field 对象都具有 Properties 集合。它 
包含所有属于各个包含对象的 Property 对象。 
ADO 对象拥有可在其上使用的诸如“整型”、“字符型”或“布尔型”这样的普通数据 
类型来设置或检索值的属性。然而,有必要将某些属性看成是数据类型“COLLECTION O 
BJECT”的返回值。相应的,集合对象具有存储和检索适合该集合的□□对象的方法。 
6.38 事件 
ADO 2.0 支持事件,事件是对某些操作将要或已经发生的通知。 
有两类事件:ConnectionEvent 和 RecordsetEvent。Connection 对象产生 Connectio 
nEvent 事件,而 Recordset 对象则产生 RecordsetEvent 事件。 
事件由事件处理程序例程处理,该例程在某个操作开始之前或结束之后被调用。 
某些事件是成对出现的。开始操作前调用的事件名格式为 WillEvent(Will 事件),而 
操作结束后调用的事件名格式为 EventComplete(Complete 事件)。其余的不成对事件 
只在操作结束后发生。(其名称没有任何固定模式。)事件处理程序由状态参数控制。 
附加信息由错误和对象参数提供。 
可以请求事件处理程序不接受第一次通知以后的任何通知。例如,可以选择只接收 Wil 
l 事件或 Complete 事件。 
下面的代码显示了一个使用ADO的例子。 
首先加入Microsoft ActiveX Data Object 2.0 Library引用。 
Dim db As Connection 
Set db = New Connection 
db.CursorLocation = adUseClient 
db.Open "PROVIDER=MSDASQL;DSN=TestDatabase", "sa", "", -1 
Dim i As Long 
Dim id As Long 
Dim value As Single 
Dim rst As New Recordset 
Set rst = New Recordset 
rst.Open "select * from 模拟量变化历史表", db, adOpenDynamic, adLockOptimist 
ic 
rst.MoveFirst 
For i = 0 To rst.RecordCount - 1 
id = rst.Fields("ID") 
value=rst.Fields(“value”) 
rst.MoveNext 
Next i 
rst.Close 
Set rst = Nothing 
db.Close 
6.4总结 
ADO技术是访问数据库的新技术,具有易于使用、访问灵活、应用广泛的特点。用ADO访 
问数据源的特点可总结如下: 
易于使用 
这是ADO技术的最重要的一个特征。由于ADO是高层应用,所以相对于OLE DB或者ODBC来 
说,它具有面向对象的特性。同时,在ADO的对象结构中,其对象之间的层次关系并不明 
显。相对于DAO等访问技术来讲,又不必关心对象的构造顺序和构造层次。对于要用的对 
象,不必选建立连接、会话等对象,只需直接构造即可,方便了应用程序的编制。 
高速访问数据源 
由于ADO技术基于OLE DB,所以,它也继承了OLE DB访问数据库的高速性。 
可以访问不同数据源 
ADO技术可以访问包括关系数据库和非关系数据库的所有文件系统。此特点使应用程序有 
很多的灵活性和通用性。 
可以用于Microsoft ActiveX页 
ADO技术可以以ActiveX控件的形式出现,所以,可以被用于Microsoft ActiveX页,此特 
征可简化WEB页的编程。 
程序占用内存少 
由于ADO是基于组件对象模型(COM)的访问技术,所以,用ADO产生的应用程序占用内存 
少。 
7、 总结 
要在访问数据时判断出应该使用哪一种技术,这并不容易。可能需要公用实用程序来处 
理多个数据库类型;部分数据可能出现在本地硬盘驱动器上,部分在网络上,还有一部 
分在主机上。甚至客户安装在设备上的产品也会使这种选择更加困难。例如,你所期待 
的ODBC支持级别也许依赖于所安装的Microsoft Office的版本,因为这个产品不提供OD 
BC支持。你还会发现,ADO类提供的对象和方法要比ODBC类多。ADO可以提供程序中绝对 
必须具有的一些特性棗例如,你会发现OLE-DB和ADO两者都支持DFX_Currency,但在ODB 
C中没有对应的功能,但你要想掌握它们也必须付出一定的努力。 
选择OLE-DB或ODBC时,有几条一般的规则。因为ADO实际上只是OLE-DB的包装,所以这些 
规则也适用于它。下面提供一些基本的原则,可以用来帮助你决定选择OLE-DB还是ODBC 
。 
非OLE环境 如果要访问支持ODBC的数据库,而该数据库又在不支持OLE的服务器上,那么 
ODBC是最好的选择。 
非SQL环境 ODBC在处理SQL时非常出众。处理非SQL数据库时,OLE-DB则具有非常明显的 
优势。 
OLE环境 对支持OLE的服务器来说,选择OLE-DB还是ODBC也许是希望各半。如果有ODBC驱 
动程序可供利用,那么使用ODBC是一个好主意;否则,就只有选择OLE-DB了。 
所需的互操作性 如果需要可互操作的数据库部件,那么只有选择OLE-DB。 
  
8、 参考书目: 
希望图书创作室译、《ODBC3程序员参考及SDK指南》、1999 
郑章、程刚、张勇等著、《Visual C++6.0数据库开发技术》、2000 
希望图书创作室译、《Visual C++6.0 技术内幕》、1999 
希望图书创作室译、《Visual C++与数据库管理》、1999 
希望图书创作室译、《Visual Basic专业版循序渐进教程》、1999 
1
表情
所有内容均为会员自愿发表,并不代表本站立场.
论坛帮助 会员认证删帖申请 联系我们