任何 SQL 语句都可能包括多个 SELECT 语句或存储过程,后者又可能调用一个或多个 SELECT 语句。每一个 SELECT 语句产生一个结果集,它必须由代码进行处理,或者在 RDO 资源被释放,并且下一个结果集成为可用的之前被放弃。
动作查询也会产生无数据行的结果集,这也是必须处理的,因为这是多结果集查询的另一种类型。在很多时候,执行一个存储过程可能会返回多个结果集。存储过程是否会返回多个结果集往往很难确定,因为存储过程可能调用了另一个过程。
例如,假设提交了一个查询,其中包括四个 SELECT 查询,用来置入到四个本地的 ListBox 控件,还包括一个事件过程,用来更新表,那么代码至少需要处理五个结果集。因为不知道会存储过程会产生多少个结果集,因此代码也就必须准备处理 n 个结果集。
执行多结果集的查询有两种方法:
这两种方法处理都很相似,但如果使用 rdoQuery 的话,可以检查 RowsAffected 属性以确定动作查询影响的数据行数。虽然也可以使用 Execute 方法执行多结果集查询,但却不能获取被单个语句影响的那些数据行,如果有的查询返回了数据行,将导致一个可以捕获的错误。
并非所有的游标驱动程序都支持对多结果集查询的处理。SQL Server 服务器端的游标驱动程序就是这样的一个例子。但是,如果使用 rdOpenForwardOnly、rdConcurReadOnly 选项,并将 RowsetSize 属性设为 1,即可请求建立一个无游标结果集,这样就可以使用服务器端的游标来执行多结果集查询。将 CursorDriver 属性设为 rdUseNone 也可为所有结果集设置这些选项。
本节将分步讲解使用 rdoQuery 对象来执行多结果集查询的步骤。
提示 在使用连接符 "&" 建立 SQL 查询时,运算符之间一定要有空格(可以用空格键或 TAB 键)。
MySQL
。对于 SQL Server,多个语句之间必须用分号分开。
Dim MySQL As String
MySQL = "Select Name from Authors Where ID = 5; " _
& " Select City from Publishers; " _
& " Update MyTable " _
& " Set Age = 18 Where Name = 'Fred'"
MyQy
。本例假定 rdoConnection 对象 (Cn
) 已经存在。有许多方法可以实例化和初始化 rdoQuery 对象,这里只介绍了其中的一种。
Dim MyQy As rdoQuery
Set MyQy = Cn.CreateQuery("MyQy1", "")
MyQy.SQL = MySQL
Dim MyRs As rdoResultset
Set MyRs = MyQy.OpenResultset(rdOpenForwardOnly, _
rdConcurReadOnly)
下述例子将查询结果填入名为 NameList1
的列表框控件中。
While Not MyRs.EOF '
循环执行所有的行。'
使用第一列。NameList1.AddItem = MyRs(0)
MyRs.MoveNext '
定位到结果集的下一行。Wend
MyRs.EOF
= True)。使用 MoreResults 方法激活下一个。一旦执行了 MoreResults 之后,第一个结果集便不再可用了,即使用游标选项来创建它。
'
激活下一个结果集。If (MyRs.MoreResults) Then ...
'
循环若干行。Do While Not MyRs.EOF and MyRs(0) < "B"
'
使用第一列。NameList1.AddItem = MyRs(0)
MyRs.MoveNext
Loop
'
激活下一个结果集,'
并废弃剩余的数据行。If (MyRs.MoreResults) Then ...
If MyQy.RowsAffected = 0 Then MsgBox "No rows were updated" End If '
激活下一个结果集。If (MyRs.MoreResults) Then ...
对最后一个结果集使用 MoreResults 方法之后,将返回 False,执行该查询所要求的其它资源也会被释放。这时,rdoQuery 对象可以再次使用。如果对 rdoQuery 使用了 Close 方法,它将从 rdoQueries 集合中删除。