You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Recordset.Find报错:Rowset不支持向后滚动(存储过程场景)

解决「Rowset does not support scrolling backward」错误的几种方案

首先,你遇到的这个错误核心原因是:sp_fkeys这类系统存储过程默认返回的是仅向前游标(forward-only),即使你指定了adOpenDynamic,在服务器端游标(adUseServer)模式下,ADODB也无法修改这个游标的属性——因为游标是由数据库服务器创建并控制的,它不支持向后滚动,自然就没法用Find方法(Find需要游标能自由移动)。

下面是几个可行的解决办法:

方案1:切换到客户端游标(最直接的修复)

把游标位置改成客户端游标(adUseClient),这样游标会在本地内存中创建,支持所有游标类型和Find方法。修改后的代码如下:

Private Sub maintablebox_Change()
 Dim cnn As ADODB.Connection
 Dim keys As ADODB.Recordset
 Set cnn = New ADODB.Connection
 connstring = "omitted"
 cnn.Open connstring
 Set keys = New ADODB.Recordset
 ' 改成客户端游标
 keys.CursorLocation = adUseClient
 query = "EXEC sp_fkeys @fktable_name = 'astAssets'"
 ' 这里可以保留adOpenDynamic,或者用adOpenStatic也可以
 keys.Open query, cnn, adOpenDynamic, adLockReadOnly
 ' 现在Find应该可以正常运行了
 keys.Find "PKTABLE_NAME = 'astAssetTypes'"
 If Not keys.EOF Then
    Debug.Print keys.Fields("FKCOLUMN_NAME")
 Else
    Debug.Print "未找到匹配的记录"
 End If
 ' 记得关闭对象
 keys.Close
 cnn.Close
 Set keys = Nothing
 Set cnn = Nothing
End Sub

注意:客户端游标会把整个记录集加载到本地内存,适合数据量不大的场景,你的sp_fkeys返回的键信息通常数据量很小,完全没问题。

方案2:直接在查询中过滤(更高效)

既然你要找特定PKTABLE_NAME的记录,不如直接在查询阶段就过滤掉不需要的数据,避免后续用Find处理。可以把sp_fkeys的结果插入临时表,再查询临时表:

Private Sub maintablebox_Change()
 Dim cnn As ADODB.Connection
 Dim keys As ADODB.Recordset
 Set cnn = New ADODB.Connection
 connstring = "omitted"
 cnn.Open connstring
 Set keys = New ADODB.Recordset
 ' 先把sp_fkeys的结果存到临时表,再查询过滤
 query = "CREATE TABLE #TempKeys (" & _
         "PKTABLE_QUALIFIER VARCHAR(128), PKTABLE_OWNER VARCHAR(128), PKTABLE_NAME VARCHAR(128), " & _
         "PKCOLUMN_NAME VARCHAR(128), FKTABLE_QUALIFIER VARCHAR(128), FKTABLE_OWNER VARCHAR(128), " & _
         "FKTABLE_NAME VARCHAR(128), FKCOLUMN_NAME VARCHAR(128), KEY_SEQ INT, UPDATE_RULE INT, " & _
         "DELETE_RULE INT, FK_NAME VARCHAR(128), PK_NAME VARCHAR(128), DEFERRABILITY INT);" & _
         "INSERT INTO #TempKeys EXEC sp_fkeys @fktable_name = 'astAssets';" & _
         "SELECT FKCOLUMN_NAME FROM #TempKeys WHERE PKTABLE_NAME = 'astAssetTypes';"
 ' 这里用默认的仅向前游标就行,因为只需要一条结果
 keys.Open query, cnn, adOpenForwardOnly, adLockReadOnly
 If Not keys.EOF Then
    Debug.Print keys.Fields("FKCOLUMN_NAME")
 Else
    Debug.Print "未找到匹配的记录"
 End If
 keys.Close
 cnn.Close
 Set keys = Nothing
 Set cnn = Nothing
End Sub

这个方案不需要修改游标类型,而且更高效,因为数据库直接帮你过滤了数据,不用把所有记录加载到客户端。

方案3:手动遍历记录集替代Find

如果因为某些原因不能改游标或查询,你可以手动遍历记录集来找到目标记录:

Private Sub maintablebox_Change()
 Dim cnn As ADODB.Connection
 Dim keys As ADODB.Recordset
 Dim found As Boolean
 Set cnn = New ADODB.Connection
 connstring = "omitted"
 cnn.Open connstring
 Set keys = New ADODB.Recordset
 keys.CursorLocation = adUseServer
 query = "EXEC sp_fkeys @fktable_name = 'astAssets'"
 keys.Open query, cnn, adOpenForwardOnly, adLockReadOnly
 found = False
 Do While Not keys.EOF
    If keys.Fields("PKTABLE_NAME").Value = "astAssetTypes" Then
        Debug.Print keys.Fields("FKCOLUMN_NAME")
        found = True
        Exit Do
    End If
    keys.MoveNext
 Loop
 If Not found Then
    Debug.Print "未找到匹配的记录"
 End If
 keys.Close
 cnn.Close
 Set keys = Nothing
 Set cnn = Nothing
End Sub

这个方法用仅向前游标遍历,虽然代码多一点,但完全避免了滚动的问题。


内容的提问来源于stack exchange,提问作者Tim Stack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:09:52