2011-05-13 73 views
2

在使用Access 97数据库的VB6项目中将ADO替换为ADO后,会发生这种情况。代码在DAO中正常但在ADO中给出运行时错误'3021'

它发生在标有“错误在这里,在下面的代码片段:

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' gves这样的解释:

“无论是EOF或BOF为True,或 当前记录已被删除。 请求的操作需要当前的 记录。“

看来,在记录的最后一条记录被删除之后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。 因此,我尽可能减少了代码,下面的代码片段可以在使用ADO的VB6上同时适用Postgresql和Access两个数据库,我试过它。

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

最终记录EOF和BOF的删除后仍然假,但你不会得到一个错误调用MoveFirst方法。调用MOVEFIRST现在将EOF和BOF设置为true,并退出循环。 相反,如果将MOVEFIRST方法替换为MOVELAST,则两个数据库都会发生(3021)错误。 在他的回答rskar引述这从MSDN

使用MoveNext方法移动 当前记录位置的一个记录 向前(朝 Recordset的底部)。如果最后一个记录是 当前记录和调用 MoveNext方法,ADO将当前 记录位置记录集中的最后 记录后(EOF为True)。 如果 EOF属性已为True,则尝试向前移动会生成 错误。

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

+2

为什么在世界上,你是通过走记录集而不是通过发出SQL DELETE语句来进行删除? – 2011-05-13 20:44:14

+0

也许是因为他认为他可以自由使用记录集对象的删除方法? – 2011-05-14 04:56:46

+0

@Phillippe正是!在我尝试从DAO转向ADO之前,它也做了很多年的工作。 – jjb 2011-05-14 08:02:37

回答

3

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

如果删除Recordset对象中最后剩下的 战绩, BOF和EOF属性可能会保持为 False,直到您尝试重新定位 当前记录。

由于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

使用MoveNext方法移动 电流记录位置一个记录 前进(朝向 记录集的底部)。如果最后一条记录是 当前记录,并且您调用 MoveNext方法,则ADO会将当前的 记录设置为记录集中最后一条 记录(EOF为True)后的位置。 如果 EOF属性已为True,则尝试向前移动会生成 错误。

+0

谢谢你解释这个。不幸的是,rset.movenext似乎不起作用,抛出同样的错误。实际上,我认为我的解决方案实际上没有。我编辑了这个问题来反映这一点。我认为有必要按照David-W-Fenton在他的评论中提出的建议进行重写。 – jjb 2011-05-14 08:06:56

+0

@jjb - 大卫的答案是最好的方法。祝你好运! – rskar 2011-05-16 19:25:45

+0

我做了一个与这个问题有关的小发现,这可能是你感兴趣的,并相应地编辑了这个问题 – jjb 2011-06-19 12:07:39

相关问题