用ADO进行数据库编程
 
 
使用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对象开发应用程序。
使用ADO对象开发应用程序可以使程序开发者更容易地控制对数据库的访问,从
而产生符合用户需求的数据库访问程序。
使用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接口,然后使用__Recordse7tPtr执行存储过程和SQL语句。
6、24 使用ADO访问数据库
__ConnectionPtr是一个连接接口,首先创建一个__ConnectionPtr接口实例,
接着指向并打开一个ODBC数据源或OLE DB数据提供者(Provider)。以下代码分
别创建一个基于DSN和非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(),adOpenDynamic,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__error对象,并将有关错误信息填充到这个对象的成员变量。6.25 类型转换
由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,
因此CString 类和COM对象是不兼容的,我们需要一组API来转换COM对象和
C++类型的数据。__vatiant__t和__bstr__t就是这样两种对象。它们提
供了通用的方法转换COM对象和C++类型的数据。
6.3 在VB中使用ADO
ADO 提供执行以下操作的方式: 
1、连接到数据源。同时,可确定对数据源的所有更改是否已成功或没有发生。
2、指定访问数据源的命令,同时可带变量参数,或优化执行。
3、执行命令。
3、如果这个命令使数据按表中的行的形式返回,则将这些行存储在易于检查、
操作或更改的缓存中。
4、适当情况下,可使用缓存行的更改内容来更新数据源。
5、提供常规方法检测错误(通常由建立连接或执行命令造成)。 
在典型情况下,需要在编程模型中采用所有这些步骤。但是,由于 ADO 有很
强的灵活性,所以最后只需执行部分模块就能做一些有用的工作。以下元素是 ADO 编程模型中的关键部分: 
6.31 连接
通过“连接”可从应用程序访问数据源,连接是交换数据所必需的环境。对象
模型使用 Connection 对象使连接概念得以具体化。
“事务”用于界定在连接过程中发生的一系列数据访问操作的开始和结束。
ADO 可明确事务中的操作造成的对数据源的更改或者成功发生,或者根本没有
发生。如果取消事务或它的一个操作失败,则最终的结果将仿佛是事务中的操
作均未发生,数据源将会保持事务开始以前的状态。对象模型无法清楚地体现
出事务的概念,而是用一组 Connection 对象方法来表示。ADO 从 OLE DB 提
供者访问数据和服务。Connection 对象用于指定专门的提供者和任意参数。6.32 命令
通过已建立的连接发出的“命令”可以某种方式来操作数据源。一般情况下,
命令可以在数据源中添加、删除或更新数据,或者在表中以行的格式检索数
据。对象模型用 Command 对象来体现命令概念。使用 Command 对象可使
 ADO 优化命令的执行。
1、 参数
通常,命令需要的变量部分即“参数”可以在命令发布之前进行更改。例如,
可重复发出相同的数据检索命令,但每一次均可更改指定的检索信息。
参数对与函数活动相同的可执行命令非常有用,这样就可知道命令是做什么
,但不必知道它如何工作。例如,可发出一项银行过户命令,从一方借出贷
给另一方。可将要过户的款额设置为参数。
对象模型用 Parameter 对象来体现参数概念。
6.33 记录集
如果命令是在表中按信息行返回数据的查询(行返回查询),则这些行将会存
储在本地。
对象模型将该存储体现为 Recordset 对象。但是,不存在仅代表单独一个
 Recordset 行的对象。
记录集是在行中检查和修改数据最主要的方法。
6.34 字段
一个记录集行包含一个或多个“字段”。如果将记录集看作二维网格,字段将
排列构成“列”。每一字段(列)都分别包含有名称、数据类型和值的属性,
正是在该值中包含了来自数据源的真实数据。
对象模型以 Field 对象体现字段。
要修改数据源中的数据,可在记录集行中修改 Field 对象的值,对记录集的
更改最终被传送给数据源。作为选项,Connection 对象的事务管理方法能够
可靠地保证更改要么全部成功,要么全部失败。
6.35 错误
错误随时可在应用程序中发生,通常是由于无法建立连接、执行命令或对某
些状态(例如,试图使用没有初始化的记录集)的对象进行操作。
对象模型以 Error 对象体现错误。
任意给定的错误都会产生一个或多个 Error 对象,随后产生的错误将会放弃
先前的 Error 对象组。
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 OBJECT”的返回值。相应的,集合对象具有存储和检索适合
该集合的其他对象的方法。
6.38 事件 
ADO 2.0 支持事件,事件是对某些操作将要或已经发生的通知。
有两类事件:ConnectionEvent 和 RecordsetEvent。Connection 对象产
生 ConnectionEvent 事件,而 Recordset 对象则产生 RecordsetEvent 事件。
事件由事件处理程序例程处理,该例程在某个操作开始之前或结束之后被调用。
某些事件是成对出现的。开始操作前调用的事件名格式为 WillEvent(Will 事
件),而操作结束后调用的事件名格式为 EventComplete(Complete 事件)。
其余的不成对事件只在操作结束后发生。(其名称没有任何固定模式。)事件
处理程序由状态参数控制。附加信息由错误和对象参数提供。
可以请求事件处理程序不接受第一次通知以后的任何通知。例如,可以选择只
接收 Will 事件或 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, adLockOptimistic
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访问数据源的特点可总结如下:
1、 易于使用
这是ADO技术的最重要的一个特征。由于ADO是高层应用,所以相对于OLE DB或
者ODBC来说,它具有面向对象的特性。同时,在ADO的对象结构中,其对象之
间的层次关系并不明显。相对于DAO等访问技术来讲,又不必关心对象的构造
顺序和构造层次。对于要用的对象,不必选建立连接、会话等对象,只需直接
构造即可,方便了应用程序的编制。
2、 高速访问数据源
由于ADO技术基于OLE DB,所以,它也继承了OLE DB访问数据库的高速性。
3、 可以访问不同数据源
ADO技术可以访问包括关系数据库和非关系数据库的所有文件系统。此特点使应
用程序有很多的灵活性和通用性。
4、 可以用于Microsoft ActiveX页
ADO技术可以以ActiveX控件的形式出现,所以,可以被用于Microsoft ActiveX
页,此特征可简化WEB页的编程。
5、 程序占用内存少
由于ADO是基于组件对象模型(COM)的访问技术,所以,用ADO产生的应用程
序占用内存少。
7、 总结
要在访问数据时判断出应该使用哪一种技术,这并不容易。可能需要公用实用
程序来处理多个数据库类型;部分数据可能出现在本地硬盘驱动器上,部分在
网络上,还有一部分在主机上。甚至客户安装在设备上的产品也会使这种选择
更加困难。例如,你所期待的ODBC支持级别也许依赖于所安装的
Microsoft Office的版本,因为这个产品不提供ODBC支持。你还会发现,
ADO类提供的对象和方法要比ODBC类多。ADO可以提供程序中绝对必须具有的
一些特性棗例如,你会发现OLE-DB和ADO两者都支持DFX_Currency,但在ODBC
中没有对应的功能,但你要想掌握它们也必须付出一定的努力。
选择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。

解决方案 »

  1.   

    一、ADO概述ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于
    使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE.DB 提供者访问
    和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速度快、内存支
    出少和磁盘遗迹小。ADO 在关键的应用方案中使用最少的网络流量,并且在前端
    和数据源之间使用最少的层数,所有这些都是为了提供轻量、高性能的接口。之
    所以称为 ADO,是用了一个比较熟悉的暗喻,OLE 自动化接口。OLE DB是一组”组件对象模型”(COM) 接口,是新的数据库低层接口,它封装
    了ODBC的功能,并以统一的方式访问存储在不同信息源中的数据。OLE DB是
    Microsoft UDA(Universal Data Access)策略的技术基础。OLE DB 为任何数据
    源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件
    系统、文本和图形、自定义业务对象等等。也就是说,OLE DB 并不局限于 
    ISAM、Jet 甚至关系数据源,它能够处理任何类型的数据,而不考虑它们的格式
    和存储方法。在实际应用中,这种多样性意味着可以访问驻留在 Excel 电子数据
    表、文本文件、电子邮件/目录服务甚至邮件服务器,诸如 Microsoft Exchange 中
    的数据。但是,OLE DB 应用程序编程接口的目的是为各种应用程序提供最佳的
    功能,它并不符合简单化的要求。您需要的API 应该是一座连接应用程序和
    OLE DB 的桥梁,这就是 ActiveX Data Objects (ADO)。
    二、在VC中使用ADO1、引入ADO库文件使用ADO前必须在工程的stdafx.h文件里用直接引入符号#import引入ADO库文件,
    以使编译器能正确编译。代码如下所示:代码1:用#import引入ADO库文件#import "c:\program files\common files\system\ado\msado15.dll"no_namespaces rename("EOF" adoEOF")这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免常数冲
    突,将常数EOF改名为adoEOF。现在不需添加另外的头文件,就可以使用ADO接口
    了。2、初始化OLE/COM库环境必须注意的是,ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初
    始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类
    的InitInstance成员函数里初始化OLE/COM库环境。 代码2:初始化OLE/COM库环境BOOL CADOApp::InitInstance(){if(!AfxOleInit()) {AfxMessageBox(“OLE初始化出错!”);return FALSE;}…… }函数AfxOleInit在每次应用程序启动时初始化OLE/COM库环境。同DAO和Cdatabase一样,ADO由几个接口组成:_ConnectionPtr,_CommandPtr和_RecordsetPtr.不同于DAO和Cdatabase的是,ADO基于COM的接口,因此,假如你没有接触过
    COM,你应该在使用ADO前先找有关书籍了解一下COM。3、ADO接口简介ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。
    _ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数
    据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用_ConnectionPtr接
    口返回一个记录集不是一个好的使用方法。通常同Cdatabase一样,使用它创建
    一个数据连接,然后使用其它对象执行数据输入输出操作。_CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集
    的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接
    口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据
    访问操作,后者是比较好的选择。但如果你要频繁访问数据库,并要返回很多记
    录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使
    用_CommandPtr接口执行存储过程和SQL语句。_RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更
    多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定
    要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的
    connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好
    的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口
    ,然后使用_RecordsetPtr执行存储过程和SQL语句。 4、使用_ConnectionPtr接口_ConnectionPtr是一个连接接口,它类似于Cdatabase和CDaoDatabase。它们的
    工作原理相似。首先创建一个_ConnectionPtr接口实例,接着指向并打开一个
    ODBC数据源或OLE DB数据提供者(Provider)。以下代码和CDaoDatabase分别创建
    一个基于DSN和非DSN的数据连接。 代码3:使用CDaoDatabase(基于DSN)CDaoDatabase MyDb = new CDaoDatabase();MyDb.Open(NULL,FALSE,FALSE,"ODBC;DSN=samp;UID=admin;PWD=admin");  代码4:使用CDaoDatabase(基于非DSN)CDaoDatabase MyDb = new CDaoDatabase();MyDb.Open(NULL,FALSE,FALSE,"ODBC;DRIVER={SQL Server};SERVER=server;DATABASE=samp;UID=admin;PWD=admin");  代码5:使用_ConnectionPtr(基于DSN)_ConnectionPtr MyDb;MyDb.CreateInstance(__uuidof(Connection));MyDb->Open("DSN=samp;UID=admin;PWD=admin","","",-1);  代码6:使用_ConnectionPtr (基于非DSN)_ConnectionPtr MyDb;MyDb.CreateInstance(__uuidof(Connection));MyDb->Open("Provider=SQLOLEDB;SERVER=server;DATABASE=samp;UID=admin;PWD=admin","","",-1); 5、使用_RecordsetPtr接口_RecordsetPtr接口的使用方法和CDaoDatabase类似,通过以下代码的比较,你
    会发现使用_RecordsetPtr接口非常简单(以下代码使用上面已经创建的数据连接): 代码7:使用CDaoDatabase执行SQL语句CDaoRecordset MySet = new CDaoRecordset(MyDb);MySet->Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM t_samp");Now using ADO:  代码8:使用_RecordsetPtr执行SQL语句_RecordsetPtr MySet;MySet.CreateInstance(__uuidof(Recordset));MySet->Open("SELECT * FROM some_table",MyDb.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);现在我们已经有了一个数据连接和一个记录集,接下来就可以使用数据了。从
    以下代码可以看到,使用ADO的_RecordsetPtr接口,就不需要象DAO那样频繁地
    使用大而复杂的数据结构VARIANT,并强制转换各种数据类型了,这也是ADO的优
    点之一。假定程序有一个名称为m_List的的ListBox控件,下面代码我们用
    _RecordsetPtr接口获取记录集数据并填充这个ListBox控件: 代码9:使用DAO访问数据VARIANT * vFieldValue;COleVariant covFieldValue;Cstring Holder;while(!MySet->IsEOF()){MySet->GetFieldValue("FIELD_1", covFieldValue);vFieldValue = (LPVARIANT)covFieldValue;if(vFieldValue->vt!-VT_NULL){Holder.Format("%s",vFieldValue->pbVal);m_List.AddString(Holder); }MySet.MoveNext(); } 代码10:使用ADO访问数据_variant_t Holdertry{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_error对象,并将有关错误信息填充到这个对象的成员变量. 6、使用_CommandPtr接口_CommandPtr接口返回一个Recordset对象,并且提供了更多的记录集控制功能,
    以下代码示例了使用_CommandPtr接口的方法: 代码11:使用_CommandPtr接口获取数据_CommandPtr pCommand;_RecordsetPtr MySet;pCommand.CreateInstance(__uuidof(Command));pCommand->ActiveConnection=MyDb;pCommand->CommandText="select * from some_table";pCommand->CommandType=adCmdText;pCommand->Parameters->Refresh();MySet=pCommand->Execute(NULL,NULL,adCmdUnknown);_variant_t TheValue = MySet->GetCollect("FIELD_1");Cstring sValue=(char*)_bstr_t(TheValue);7、关于数据类型转换由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,
    因此Cstring 类和COM对象是不兼容的,我们需要一组API来转换COM对象和C++
    类型的数据。_vatiant_t和_bstr_t就是这样两种对象。它们提供了通用的方法
    转换COM对象和C++类型的数据。8、小结数据访问发展的趋势是OLE DB.使用OLE DB最简单的方法是ADO.ADO的对象层次模
    型封装了数据库访问细节,为C++程序员提供了一种非常好的数据访问策略。