在VC++中使用ADOWord格式.docx
《在VC++中使用ADOWord格式.docx》由会员分享,可在线阅读,更多相关《在VC++中使用ADOWord格式.docx(18页珍藏版)》请在冰豆网上搜索。
含有由Field对象组成的Fields集合。
每个Field对象对应于Recordset中的一列。
使用Field对象的Value属性可设置或返回当前记录的数据。
Parameter
代表与基于参数化查询或存储过程的Command对象相关联的参数或自变量
Property
对象代表由提供者定义的ADO对象的动态特征
RecordSet
表示的是来自基本表或命令执行结果的记录全集。
任何时候,Recordset对象所指的当前记录均为集合内的单个记录
2.1.Command对象
使用Command对象查询数据库并返回Recordset对象中的记录,以便执行大量操作或处理数据库结构。
可以使用Command对象的集合、方法、属性进行下列操作:
∙使用CommandText属性定义命令(例如,SQL语句)的可执行文本。
∙通过Parameter对象和Parameters集合定义参数化查询或存储过程参数。
∙可使用Execute方法执行命令并在适当的时候返回Recordset对象。
∙执行前应使用CommandType属性指定命令类型以优化性能。
∙使用Prepared属性决定提供者是否在执行前保存准备好(或编译好)的命令版本。
∙使用CommandTimeout属性设置提供者等待命令执行的秒数。
∙通过设置ActiveConnection属性使打开的连接与Command对象关联。
∙设置Name属性将Command标识为与Connection对象关联的方法。
∙将Command对象传送给Recordset的Source属性以便获取数据。
注意
如果不想使用Command对象执行查询,请将查询字符串传送给Connection对象的Execute方法或Recordset对象的Open方法。
但是,当需要使命令文本具有持久性并重新执行它,或使用查询参数时,则必须使用Command对象。
要执行Command,只需通过它所关联的Connection对象的Name属性,将其简单调用即可。
必须将Command的ActiveConnection属性设置为Connection对象。
如果Command带有参数,则将这些参数的值作为参数传送给方法。
如果在相同连接上执行两个或多个Command对象,并且某个Command对象是带输出参数的存储过程,这时会发生错误。
要执行各个Command对象,请使用独立的连接或将所有其他Command对象的连接断开。
2.2Connection对象
Connection对象代表与数据源进行的唯一会话。
如果是客户端/服务器数据库系统,该对象可以等价于到服务器的实际网络连接。
取决于提供者所支持的功能,Connection对象的某些集合、方法或属性有可能无效。
使用Connection对象的集合、方法、和属性可执行下列操作:
∙在打开连接前使用ConnectionString、ConnectionTimeout和Mode属性对连接进行配置。
∙设置CursorLocation属性以便调用支持批更新的“客户端游标提供者”。
∙使用DefaultDatabase属性设置连接的默认数据库。
∙使用IsolationLevel属性为在连接上打开的事务设置隔离级别。
∙使用Provider属性指定OLEDB提供者。
∙使用Open方法建立到数据源的物理连接。
使用Close方法将其断开。
∙使用Execute方法执行对连接的命令,并使用CommandTimeout属性对执行进行配置。
∙可使用BeginTrans、CommitTrans和RollbackTrans方法以及Attributes属性管理打开的连接上的事务(如果提供者支持则包括嵌套的事务)。
∙使用Errors集合检查数据源返回的错误。
∙通过Version属性读取使用中的ADO执行版本。
∙使用OpenSchema方法获取数据库模式信息。
如果不使用Command对象执行查询,请向Connection对象的Execute方法传送查询字符串。
但是,当需要使命令文本具有持久性并重新执行,或使用查询参数的时候,则必须使用Command对象。
可以创建独立于先前定义的其他任何对象的Connection对象。
可以象执行Connection对象的本地方法一样执行命令或存储过程。
如果要执行命令,可以使用Command对象的Name属性给命令指定一个名称。
将Command对象的ActiveConnection属性设置为该连接。
然后,象发出Connection对象的方法一样发出使用命令名称的语句,后面可带任何参数(如果有返回行,则后面带Recordset对象
2.3.Error对象
每个错误出现时,一个或多个Error对象将被放到Connection对象的Errors集合中。
当另一个ADO操作产生错误时,Errors集合将被清空,并在其中放入新的Error对象集。
每个Error对象都代表特定的提供者错误而不是ADO错误,ADO错误被记载到运行时的例外处理机制中。
例如,在MicrosoftVisualBasic中,产生特定ADO的错误将触发OnError事件并出现在Err对象中。
关于ADO错误的完整列表,请参阅ADO错误代码主题。
通过Error对象的属性可获得每个错误的详细信息,其中包括以下内容:
∙Description属性,包含错误的文本。
∙Number属性,包含错误常量的长整型整数值。
∙Source属性,标识产生错误的对象。
在向数据源发出请求之后,如果Errors集合中有多个Error对象,则将会用到该属性。
∙SQLState和NativeError属性,提供来自SQL数据源的信息。
出现提供者错误时,Error对象将被放在Connection对象的Errors集合中。
ADO支持由单个ADO操作返回多个错误,以便显示特定提供者的错误信息。
要在错误处理程序中获得丰富的错误信息,可使用相应的语言或所在工作环境下的错误捕获功能,然后使用嵌套循环枚举出Errors集合的每个Error对象的属性。
与提供者一样,ADO在进行可能引发新的提供者错误的调用前将清除OLEErrorInfo对象。
但是,只有当提供者产生新的错误或Clear方法被调用时,才能清空并充填Connection对象的Errors集合。
某些属性和方法返回的警告以Errors集合中的Error对象的方式出现,但并不中止程序的执行。
在调用Recordset对象的Resync、UpdateBatch、或CancelBatch方法,或Connection对象的Open方法,或者在设置Records对象的Filter属性之前,可通过调用Errors集合的Clear方法。
这样就可以读取Errors集合的Count属性,以测试返回的警告。
2.4.Field对象
Recordset对象含有由Field对象组成的Fields集合。
取决于提供者具有的不同功能,Field对象的某些集合、方法或属性有可能无效。
使用Field对象的集合、方法、和属性可进行如下操作:
∙使用Name属性可返回字段名。
∙使用Value属性可查看或更改字段中的数据。
∙使用Type、Precision和NumericScale属性可返回字段的基本特性。
∙使用DefinedSize属性可返回已声明的字段大小。
∙使用ActualSize属性可返回给定字段中数据的实际大小。
∙使用Attributes属性和Properties集合可决定对于给定字段哪些类型的功能受到支持。
∙使用AppendChunk和GetChunk方法可处理包含长二进制或长字符数据的字段值。
∙如果提供者支持批更新,可使用OriginalValue和UnderlyingValue属性在批更新期间解决字段值之间的差异。
在打开Field对象的Recordset前,所有元数据属性(Name、Type、DefinedSize,Precision和NumericScale)都是可用的。
在此时设置这些属性将有助于动态构造其格式。
2.5.Parameter对象
许多提供者都支持参数化的命令。
需要进行的操作在这些命令中只定义一次,但可以使用变量(或参数)改变命令的某些细节。
例如,SQLSELECT语句可使用参数定义WHERE子句的匹配条件,而使用另一个参数来定义SORTBY子句的列的名称。
Parameter对象代表与参数化查询关联的参数,或进/出参数以及存储过程的返回值。
取决于提供者的功能,Parameter对象的某些集合、方法或属性有可能无效。
使用Parameter对象的集合、方法、和属性可进行如下操作:
∙使用Name属性可设置或返回参数名称。
∙使用Value属性可设置或返回参数值。
∙使用Attributes和Direction、Precision、NumericScale、Size以及Type属性可设置或返回参数特性。
∙使用AppendChunk方法可将长整型二进制或字符数据传递给参数。
如果知道与想要调用的存储过程或参数化查询相关联的参数属性和名称,则可使用CreateParameter方法创建带有相应属性设置的Parameter对象,并使用Append方法将它们添加到Parameters集合。
这样就可以设置并返回参数值,而无需调用Parameters集合的Refresh方法来检索提供者的参数信息,即潜在的、资源集中的操作。
2.6.Property对象
ADO对象有两种类型的属性:
内置属性和动态属性。
内置属性是在ADO中实现并立即可用于任何新对象的属性,此时使用MyObject.Property语法。
它们不会作为Property对象出现在对象的Properties集合中,因此,虽然可以更改它们的值,但无法更改它们的特性。
动态属性由基本的数据提供者定义,并出现在相应的ADO对象的Properties集合中。
例如,指定给提供者的属性可能会指示Recordset对象是否支持事务或更新。
这些附加的属性将作为Property对象出现在该Recordset对象的Properties集合中。
动态属性只能通过集合使用MyObject.Properties(0)或MyObject.Properties("
Name"
)语法来引用。
两种属性都无法删除。
动态Property对象有四个自己的内置属性:
∙Name属性是标识属性的字符串。
∙Type属性是用于指定属性数据类型的整数。
∙Value属性是包含属性设置的变体型。
∙Attributes属性是指示特定于提供者的属性特征的长整型值。
2.7.RecordSet对象
可使用Recordset对象操作来自提供者的数据。
使用ADO时,通过Recordset对象可对几乎所有数据进行操作。
所有Recordset对象均使用记录(行)和字段(列)进行构造。
由于提供者所支持的功能不同,某些Recordset方法或属性有可能无效。
ADOR.Recordset和ADODB.Recordset是用来创建Recordset对象的ProgID。
由此产生的Recordset对象行为相同,与ProgID无关。
ADOR.Recordset随Microsoft®
InternetExplorer安装,而ADODB.Recordset则随ADO安装。
Recordset对象的行为受环境(即客户端、服务器、InternetExplorer等)的影响。
这些差异将在属性、方法和事件的“帮助”主题中加以说明。
在ADO中定义了四种不同的游标类型:
∙动态游标—用于查看其他用户所作的添加、更改和删除,并用于不依赖书签的Recordset中各种类型的移动。
如果提供者支持,可使用书签。
∙键集游标—其行为类似动态游标,不同的只是禁止查看其他用户添加的记录,并禁止访问其他用户删除的记录,其他用户所作的数据更改将依然可见。
它始终支持书签,因此允许Recordset中各种类型的移动。
∙静态游标—提供记录集合的静态副本以查找数据或生成报告。
其他用户所作的添加、更改或删除将不可见。
这是打开客户端(ADOR)Recordset对象时唯一允许使用的游标类型。
∙仅向前游标—除仅允许在记录中向前滚动之外,其行为类似静态游标。
这样,当需要在Recordset中单程移动时就可提高性能。
在打开Recordset之前设置CursorType属性来选择游标类型,或使用Open方法传递CursorType参数。
部分提供者不支持所有游标类型。
请检查提供者的文档。
如果没有指定游标类型,ADO将默认打开仅向前游标。
如果CursorLocation属性被设置为adUseClient后打开Recordset,则在返回的Recordset对象中,Field对象的UnderlyingValue属性不可用。
对部分提供者(例如MicrosoftODBCProviderforOLEDB连同MicrosoftSQLServer),可以通过使用Open方法传递连接字符串,根据以前定义的Connection对象独立地创建Recordset对象。
ADO仍然创建Connection对象,但它不将该对象赋给对象变量。
不过,如果正在相同的连接上打开多个Recordset对象,就应该显式创建和打开Connection对象,由此将Connection对象赋给对象变量。
如果在打开Recordset对象时没有使用该对象变量,即使在传递相同连接字符串的情况下,ADO也将为每个新的Recordset创建新的Connection对象。
可以创建所需数量的Recordset对象。
打开Recordset时,当前记录位于第一个记录(如果有),并且BOF和EOF属性被设置为False。
如果没有记录,BOF和EOF属性设置是True。
假设提供者支持相关的功能,可以使用MoveFirst、MoveLast、MoveNext和MovePrevious方法以及Move方法,和AbsolutePosition、AbsolutePage和Filter属性来重新确定当前记录的位置。
仅向前Recordset对象只支持MoveNext方法。
当使用Move方法访问每个记录(或枚举Recordset)时,可使用BOF和EOF属性查看是否移动已经超过了Recordset的开始或结尾。
Recordset对象可支持两类更新:
立即更新和批更新。
使用立即更新,一旦调用Update方法,对数据的所有更改将被立即写入基本数据源。
也可以使用AddNew和Update方法将值的数组作为参数传递,同时更新记录的若干字段。
如果提供者支持批更新,可以使提供者将多个记录的更改存入缓存,然后使用UpdateBatch方法在单个调用中将它们传送给数据库。
这种情况应用于使用AddNew、Update和Delete方法所做的更改。
调用UpdateBatch方法后,可以使用Status属性检查任何数据冲突并加以解决。
要执行不使用Command对象的查询,应将查询字符串传递给Recordset对象的Open方法。
但是,在想要保持命令文本并重复执行或使用查询参数时,仍然需要Command对象。
3.ADO在VC++中的具体使用方法
3.1ADO接口简介
接口2
接口1
服务器
客户
COM把组件应用程序分成了两部分:
COM服务器和COM客户,如图所示。
COM服务器的任务就是提供组件模块,而COM客户就是使用COM服务器所提供的组件的应用程序。
客户必须通过组件的接口才能获得服务器的服务,也就是说客户只能通过接口与组件进行通信。
那么什么是接口呢?
从客户的角度看,接口就是组件暴露在外部,从而使客户可以访问的方法;
从组件的角度看,接口是一组功能相关的函数集合,COM规定,一个组件对象可以拥有多个接口。
ADO库包含三个基本接口:
_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。
(1)_ConnectionPtr接口返回一个记录集或一个空指针。
通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
但是使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。
对于要返回记录的操作通常用_RecordserPtr来实现。
两者的区别则是:
_ConnectionPtr操作时要想得到记录条数得遍历所有记录,而用_RecordserPtr时不需要。
(2)_CommandPtr接口返回一个记录集。
它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。
在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。
如果只执行一次或几次数据访问操作,使用_CommandPtr接口是比较好的选择。
但是如果要频繁访问数据库,并要返回很多记录集,那么,就应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。
(3)_RecordsetPtr是一个记录集对象。
与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。
它同_CommandPtr接口一样,不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。
如果要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口然后使用_RecordsetPtr执行存储过程和SQL语句。
3.2在VC中使用的基本流程及所需代码
为了能更详细的描述我们用VC++建立一个新的MFC应用程序ADOCtrAccess,下文所涉及到的语句都以这一应用程序为基础。
(1)引入ADO库定义文件。
在工程中引入库定义文件需要在StdAfx.h文件中添加一下语句:
#import"
C:
\ProgramFiles\CommonFiles\System\ADO\msado15.dll"
rename_namespace("
ADOCG"
)rename("
EOF"
"
adoEOF"
)
其中C:
\ProgramFiles\CommonFiles\System\ADO\msado15.dll为系统安装的ADO支持文件的路径,这个路径名可以根据自己系统安装的ADO支持文件的路径来自行设定。
当编译器遇到#import语句时,它会为引用组件类型库中的接口生成包装类,#import语句实际上相当于执行了API涵数LoadTypeLib()。
#import语句会在工程可执行程序输出目录中产生两个文件,分别为*.tlh(类型库头文件)及*.tli(类型库实现文件),它们分别为每一个接口产生智能指针,并为各种接口方法、枚举类型,CLSID等进行声明,创建一系列包装方法。
语句no_namespace说明ADO对象不使用命名空间,rename(“EOF”,“adoEOF”)说明将ADO中结束标志EOF改为adoEOF,以避免和其它库中命名相冲突。
(2)初始化COM库。
ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。
在程序初始过程中需要初始化组件,一般可以用CoInitialize(NULL);
来实现,这种方法在结束时要关闭初始化的COM,可以用下面语句CoUnInitialize();
来实现。
在MFC中还可以采用另一种方法来实现初始化COM,那就是使用AfxOleInit();
语句,使用这一语句便可以自动为我们实现初始化COM和结束时关闭COM的操作,具体语句如下所示:
A.使用CoInitialize(NULL);
语句进行初始化:
intCADOCtrAccessView:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
:
CoInitialize(NULL)
AfxEnableControlContainer();
……
returnTRUE;
}
B.使用AfxOleInit();
BOOLCADOCtrAccessApp:
:
InitInstance()
if(!
AfxOleInit())
AfxMessageBox(“OLE初始化出错!
”);
returnFALSE;
}
(3)连接数据库。
打开一个数据库连接。
要先用_ConnectionPtr接口创建一个实例指针对象,再用调用Open方法打开数据库连接,它将返回一个