从 RDO到 ADO 的移植
陈永浩
当前Microsoft 的最新数据访问技术 ActiveX Data Objects (ADO) 非常流行。ADO 是以前的 DAO、尤其是 RDO 数据访问接口的一个替代,它提供了前两者都不具备的附加功能。
本文主要讨论如何把正使用 RDO 进行的数据访问虑移植到 ADO 上,以便大家使用 ADO 转换自己的应用程序。
一、ADO 和 RDO、DAO 的比较
ADO 并不是自动和您现存的数据访问应用程序代码兼容的。当 ADO 封装 DAO 和 RDO 的功能性的时候,就必须将许多语言要素转换为 ADO 语法。在某些情况下,您可以将现存代码的某些功能做一个简单转换。在其他情况下,最好是用 ADO 的新功能重写该应用程序。
DAO (Data Access Objects) 数据访问对象是第一个面向对象的接口,它显露了 Microsoft Jet 数据库引擎(由 Microsoft Access 所使用),并允许 Visual Basic 开发者通过 ODBC 象直接连接到其他数据库一样,直接连接到 Access 表。DAO 最适用于单系统应用程序或小范围本地分布使用。
RDO (Remote Data Objects) 远程数据对象是一个到 ODBC 的、面向对象的数据访问接口,它同易于使用的 DAO style组合在一起,提供了一个接口,形式上展示出所有 ODBC 的底层功能和灵活性。尽管 RDO 在很好地访问 Jet 或 ISAM 数据库方面受到限制,而且它只能通过现存的 ODBC 驱动程序来访问关系数据库。但是,RDO 已被证明是许多 SQL Server、Oracle 以及其他大型关系数据库开发者经常选用的最佳接口。RDO 提供了用来访问存储过程和复杂结果集的更多和更复杂的对象、属性,以及方法。
ADO 是 DAO/RDO 的后继产物。ADO 2.0在功能上与 RDO 更相似,而且一般来说,在这两种模型之间有一种相似的映射关系。ADO "扩展"了 DAO 和 RDO 所使用的对象模型,这意味着它包含较少的对象、更多的属性、方法(和参数),以及事件。例如,ADO 没有与 rdoEngine 和 rdoEnvironment 对象相等同的对象,可以显露 ODBC 驱动程序管理器和 hEnv 接口。虽然您的接口可能是通过 ODBC OLE DB 服务提供程序实现的,但您当前也不能从 ADO 中创建 ODBC 数据源。
包含在 DAO 和 RDO 模型中的许多功能被合并为单个对象,这样就生成了一个简单得多的对象模型。然而,由于这个原因,起初您可能会觉得找到合适的 ADO 对象、集合、属性、方法,或事件非常困难。与 DAO 和 RDO不同的是,虽然 ADO 对象是分层结构的,但在分层结构范围之外也是可以创建的。
不过,也应当注意,ADO 当前并不支持 DAO 的所有功能。ADO 主要包括 RDO 风格的功能性,以便和 OLE DB 数据源交互,另外还包括远程和 DHTML 技术。
一般说来,在 ADO 的演化过程中,马上把大多数 DAO 应用程序移植到 ADO 上可能为时太早,因为当前的 ADO 并不支持数据定义 (DDL)、用户、组,等等。不过,如果您只将 DAO 用于客户-服务器应用程序,而并不依赖于 Jet 数据库引擎或不使用 DDL,那么现在就可能移植到 ADO。最终,Microsoft 将提供一个 ADO DDL 部件来帮助进行 DAO 到 ADO 的移植,并为 OLE DB 供应商提供一般的 DDL 支持。
二、如何在 Visual Basic 中引用 ADO 2.0
要在 Visual Basic 中对 ADO 2.0 对象进行访问,可设置对合适的 ADO 类型库的访问。有两种 ADO 类型库。一种叫 ADODB,包含在 MSADO15.DLL 中。它以"Microsoft ActiveX Data Objects 2.0 Library"出现在"工程"菜单中"引用..." 中。另一种叫做 ADOR,包含在 MSADOR15.DLL 中。它以"Microsoft ActiveX Data Objects Recordset 2.0 Library"出现在"引用..."对话框中。
在两种类型库中,第一种类型库 (ADODB) 更大,具有更多功能;它包含了主要的 ADO 对象,而且可能在大多数情况下使用。第二种是只支持记录集的 ADODB 类型库的一个"轻量"子集。如果只想操作记录集的话,就可以选择使用该类型库。
三、ADO 2.0 对象模型
ADO 2.0 对象模型由八个对象组成的,它们中的大多数在功能上和 RDO 对象相似,只不过具有更强的功能性而已。需要花一些时间在 Object Browser (F2) 中浏览对象模型,以便于熟悉各种不同属性、方法、事件、集合等等所在的位置。
注意 所有后面带有星号 (*) 的对象都是同时应用于 ADO Recordset 类型库 (ADOR) 的对象。
· Command 对象 包含关于某个命令,例如查询字符串、参数定义等的信息。Command 对象在功能上和 RDO 的 rdoQuery 对象是相似的。
· Connection 对象 包含关于某个数据提供程序的信息。Connection 对象在功能上和 RDO 的 rdoConnection 对象是相似的,并且包含了关于结构描述的信息。它还包含某些 RDOEnvironment 对象的功能,例如 transaction 控件。
· Error 对象 包含数据提供程序出错时的扩展信息。Error 对象在功能上和 RDO 的 rdoError 对象是相似的。
· Field 对象* 包含记录集中数据的某单个列的信息。Field 对象在功能上和 RDO 的 rdoColumn 对象是相似的。
· Parameter 对象 包含参数化的 Command 对象的某单个参数的信息。该 Command 对象有一个包含其所有 Parameter 对象的 Parameters 集合。Parameter 对象在功能上和 RDO 的 rdoParameter 对象是相似的。
· Property 对象* 包含某个 ADO 对象的提供程序定义的特征。没有任何等同于该对象的 RDO,但 DAO 有一个相似的对象。ADO 对象可以具有两种属性:
· Built-In 属性:ADO 的"本地"属性。也就是说,任何使用熟悉的 MyObject.Property 语法的新对象都可以立即使用的 ADO 中的属性。Built-in 属性并不在某个对象的 Properties 集合中以 Property 对象的形式出现,因此尽管您可以修改它们的值,您却不能修改它们的特性或将它们删除。
· Dynamic 属性:ADO 的非本地属性,它们是由下一级数据提供程序定义的。它们出现在合适的 ADO 对象的 Properties 集合中。
例如,一个数据提供程序特有的属性可能指明某个 Recordset 对象是支持事务还是支持更新。这些附加的属性在 Recordset 的 Properties 集合中以 Property 对象的形式出现。Dynamic 属性只能用 MyObject.Properties(0) 或 MyObject.Properties("Name") 语法通过集合来引用。不同的数据提供程序可能提供一个或多个特殊的属性,来处理提供程序特有的操作。
· Recordset 对象* Recordset 对象包含某个查询返回的记录,以及那些记录中的游标。Recordset 对象在功能上和 RDO 的 rdoResultset 对象相似。您可以在不用显式地打开 Connection 对象的情况下,打开一个 Recordset(例如,执行一个查询)。不过,如果您选择创建一个 Connection 对象,您就可以在同一个连接上打开多个 Recordset 对象。
四、一般数据访问的移植
下面列出了两个基本的数据访问方案,每个方案都在后面的主题中进行了讨论。在每种方案中,都介绍了一种 RDO 解决方案和一种 ADO 解决方案。
· 建立到某个数据库的连接
· 运行一个基本查询
注意 部分示例引用了某个窗体上的附加控件,例如一个 MSHFlexGrid 控件或 TextBox 控件。为使自己的工程能够正常工作,请把这些控件添加到工程中。
1。建立到某个数据库的连接
1.> RDO
要打开一个连接,必须提供一个带参数的连接字符串。注意当 RDO 要创建一个 rdoQuery 对象时,是不需要连接的,但当最初创建一个 rdoResultset 对象时,则是需要的:
Dim cn As New rdoConnection
Dim cnB As New rdoConnection
Const ConnectionString = "uid=myname;pwd=mypw;driver={SQLServer}; _
server=myserver;database=pubs;dsn=''"
该连接字符串访问一个特定的 SQL Server,并允许 ODBC 在没有 DSN 的情况下打开一个连接。这是一个带有所有标准参数的典型 ODBC 连接字符串。
下一节代码,在窗体的 Load 事件中,建立了游标驱动程序的类型以及登录超时。缺省情况下,RDO 使用 rdUseIfNeeded 游标类型,该类型调用 SQL Server 上服务器端的游标。下面的示例中指定了 rdUseNone,从而使这种缺省规定不被遵守。rdDriverNoPrompt 标志意味着如果用户ID 和密码不匹配,应用程序将产生一个错误。
Private Sub Form_Load()
With cn
cn.Connect = ConnectString
cn.LoginTimeout = 10
cn.CursorDriver = rdUseNone
cn.EstablishConnection rdDriverNoPrompt
End With
第二个连接执行任何客户批处理更新:
With cnB
cnB.Connect = ConnectString
cnB.CursorDriver = rdUseClientBatch
cnB.EstablishConnection
End With
End Sub
当连接操作完成时最后一个事件发生,并且它能够对连接打开时所出现的任何错误进行处理。可以用该事件来测试连接是否正常工作,如果能正常工作,则使任何依赖于打开连接的按钮都成为有效的。
Private Sub cn_Connect(ByVal ErrorOccurred As Boolean)
If ErrorOccurred Then
MsgBox "Could not open connection", vbCritical
Else
RunOKFrame.Enabled = True
End If
End Sub
2.>ADO
要在 ADO 中建立一个数据库连接,首先创建一组可被 ADODB 对象引用的 ADO 对象。这些对象将在以后用于设置打开连接和generate结果集的特定属性:
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim cnB As New ADODB.Connection
Dim Qy As New ADODB.Command
下一行创建了一个连接字符串,正如您在前一个 RDO 示例中所创建的那样。在两种情况下,您都使用 ODBC 的 "非-DSN" 连接策略以节省时间,并提高性能:
Const ConnectionString = "uid=myname;pwd=mypw;driver={SQL Server}; _
server=myserver;database=pubs;dsn=",,connection=adConnectAsync"
下面的声明对本示例中用到的变量进行初始化。(注意一个保存结果集的变量数组的创建):
Dim sql As String
Dim rc As Integer
Dim i As Integer
Dim Changes As Integer
Dim bms() As Variant
下一步,打开一个到 Form_Load 事件中某个数据库的 ADO 连接。注意该代码和 RDO 代码是很相似的,只不过常数是以 "ad" 开始的,而不是 "rd"。如果要看到所有可以使用的常数,请查看 ADODB 类型库。
注意 不需要指定提示行为,因为 ADO 的缺省设置为"无提示"。不过,如果您选择对之进行更改,则可以使用 ADO Properties 集合来处理希望的提示行为。在 RDO 中,您可以用 OpenConnection 参数来设置行为。在 ADO 中,您必须设置 Properties ("Prompt") 属性。
同时,如果您不想使用游标驱动程序,则不必对其进行指定(象在 RDO 中的CursorDriver = rdUseNone),因为 ADO 的缺省规定是无游标驱动程序。
Private Sub Form_Load()
With cn
' 建立非 DSN 连接
.ConnectionString = ConnectString
.ConnectionTimeout = 10
'.Properties("Prompt") = adPromptNever
' This is the default prompting mode in ADO.
.Open
End With
With cnB
.ConnectionString = ConnectString
.CursorLocation = adUseClient
.Open
End With
End Sub
2。运行一个基本查询
1.>RDO
该事件过程返回一个基于 SQL 语句的结果集。它执行一个受限查询,并将结果集传递到一个控件,该控件将结果数据插入到某个 MSHFlexGrid 控件中。注意,建立结果集需要一个打开的连接。
Private Sub RunButton_Click()
Dim rs As rdoResultset
Set rs = cn.OpenResultset("select * from titles where title _
like '%h'")
rdoGrid1.ShowData rs
rs.Close
End Sub
2.>ADO
一旦打开了数据库连接,您就可以对其运行一个查询。下面的事件过程和先前的 RDO 代码是非常相似的。不过,在这种情况下,您用进行 SQL 查询的新 ADO Open 方法和 ADO Connection 对象作为参数,而不是使用 rdoConnection 对象的 OpenResultset 方法。您也可以选择使用 ADO Connection 对象的 Execute 方法,就象您可以在 RDO 中所做的那样(只要它不返回一个行集合)。
ADO2 和 RDO2 相比,一个主要的不同之处在于 ADO2 允许您创建一个记录集,并在打开该记录集之前对其属性进行设置。
Private Sub RunButton_Click()
Dim rs As New ADODB.Recordset
rs.Open "select * from titles where title like '%h'", cn
ADOGrid1.ShowData rs
rs.Close
End Sub
您可以运行该查询,并在 ADO 中异步地处理其结果集。也就是说,you specify the adFetchAsynch option on rs.Open,ADO 导致游标驱动程序自动充填背景中的结果集。
如果您有问题,请发 Eamil :
[email protected]
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=3345