ms-access - 代码在 DAO 中没问题,但在 ADO 中出现运行时错误 '3021'

标签 ms-access vb6 ado dao

在使用 Access 97 数据库的 VB6 项目中用 ADO 替换 DAO 后会发生这种情况。

它发生在以下代码段中标记为“Error Here”的行上:

If rset.BOF <> True Or rset.EOF <> True Then
  rset.MoveLast 
  Do While rset.BOF <> True
     rset.Delete
     If rset.BOF <> True Or rset.EOF <> True Then  
         rset.MoveLast    'Error Here
     End If
   Loop
End If

运行时错误“3021”给出了以下解释:

"Either EOF or BOF is True, or the current record has been deleted. requested operation requires a current record."



似乎在记录集中的最后一条记录被删除后 BOF +/- EOF 在代码的 ADO 版本中仍然为假,而在 DAO 版本中两者都为真。
如果我像这样更改代码,它会起作用

编辑:以下代码不起作用。当我尝试这个“解决方案”时,所有的记录
已经从表中删除,因此整个块被绕过,因此没有抛出错误。很抱歉提供了不好的信息。

If rset.BOF <> True Or rset.EOF <> True Then
      rset.MoveLast 
      Do While rset.BOF <> True
         rset.Delete
         If rset.BOF <> True Or rset.EOF <> True Then 
         End If
         If rset.BOF <> True Or rset.EOF <> True Then  
             rset.MoveLast    
         End If
       Loop
End If

有人可以解释一下吗? (理想情况下提供不涉及更改代码的解决方案!)

进一步编辑:据我所知,尝试了很多方法后,BOF 和 EOF 在 ADO 中对于测试删除后的空记录集是无用的。这是因为您需要使用一种移动方法来更新 BOF/EOF,如果记录集为空,您将收到错误消息。在我使用的记录集上,RecordCount 属性在删除后更新。虽然我不打算使用它,但这段代码确实有效:
If rset.BOF <> True Or rset.EOF <> True Then
   Do While rset.RecordCount > 0
      rset.MoveLast
      rset.Delete
   Loop
End If

编辑(1 个月后)
因此,在重写了一大堆代码之后,我遇到了一个包含没有给出错误的删除的循环。唯一的区别是这个循环每次都删除记录集中的第一条记录而不是最后一条,因此在每次删除后它都会执行
MOVEFIRST 而不是 MOVELAST。
所以我尽可能地减少了代码,下面的代码片段在 Postgresql 和 Access 上都可以正常工作,这是我在 VB6 上使用 ADO 尝试过的两个数据库。

Do While rset.EOF <> True
     rset.Delete
     rset.MoveFirst
Loop

删除最后一条记录后,EOF 和 BOF 仍然是假的,但调用 MOVEFIRST 方法不会出错。现在调用 MOVEFIRST 将 EOF 和 BOF 都设置为 true 并退出循环。
相比之下,如果将 MOVEFIRST 方法替换为 MOVELAST,则两个数据库都会出现 (3021) 错误。
rskar 在他的回答中引用了 MSDN


Use the MoveNext method to move the current record position one record forward (toward the bottom of the Recordset). If the last record is the current record and you call the MoveNext method, ADO sets the current record to the position after the last record in the Recordset (EOF is True). An attempt to move forward when the EOF property is already True generates an error.



他们提到 MOVENEXT 会导致错误,我想因为 MOVELAST 是在同一方向上运动,这解释了为什么它也会导致错误。
我只是希望我没有假设所有的移动方法都会导致类似的问题

最佳答案

http://msdn.microsoft.com/en-us/library/ms675787(v=vs.85).aspx :

If you delete the last remaining record in the Recordset object, the BOF and EOF properties may remain False until you attempt to reposition the current record.



由于 ADO 不是 DAO,因此行为上的差异不应该太令人惊讶。似乎对 MoveLast 的调用可能会触发对 BOF/EOF 的更新。我认为您可能会被迫进行编码更改。

对于踢腿和傻笑,试一试(不知道它是否会奏效):
rset.Delete 
rset.MoveNext
If rset.BOF <> True Or rset.EOF <> True Then                 
    rset.MoveLast               
End If

http://msdn.microsoft.com/en-us/library/ms677527(v=vs.85).aspx :

Use the MoveNext method to move the current record position one record forward (toward the bottom of the Recordset). If the last record is the current record and you call the MoveNext method, ADO sets the current record to the position after the last record in the Recordset (EOF is True). An attempt to move forward when the EOF property is already True generates an error.

关于ms-access - 代码在 DAO 中没问题,但在 ADO 中出现运行时错误 '3021',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5995071/

相关文章:

sql - 如何强制总列最后出现在 TRANSFORM SQL 语句中

database - 数据库之间的数据传输测量

windows - VB6 Dir ("*.dot") 在一台服务器上通配找到 .dotx,但在另一台服务器上找不到

.net - 从远程桌面中运行的应用程序,如何以编程方式获取已复制到客户端剪贴板的文件并将其保存到磁盘

sql-server - 如何从 Delphi 运行数据库脚本文件?

xml - 使用 ado 对象使用 'save' 方法更改 xml 导出字段的精度

sql - ms-access 列表框怪异(内存问题?)

vb.net - 相当于 "Open fileName For Output As #1"VB6 到 .NET

c++ - c\c++ 中存储 COM 的 VT_DECIMAL 的正确类型是什么?