'cursor is in BOF position' 错误

'cursor is in BOF position' error

在删除 table 之前,我有 :

procedure TData_Module.MyTableBeforeDelete(DataSet: TDataSet);
begin    
if MessageDlg('Are you sure you want to delete the record written by '+
                  QuotedStr(MyTable.FieldByName('written_by_who').AsString),mtConfirmation,[mbYes,mbNo],0) = mrYes then
    MyTable.Delete;
end;

但是,在尝试时出现错误: ...光标在 BOF 位置

怎么回事?数据库准确无误。

编辑:上面的完整代码:)

正如我在评论中所说的那样,从您的 q 听起来好像您在数据集的 BeforeDelete 事件中调用 Delete。不要那样做,因为当数据集已经在删除记录的过程中时会发生 BeforeDelete 事件。所以你删除它是从数据集的内置代码中取出地毯。

因此,如果您想要用户确认,请在调用 Delete 之前获取它,而不是在 BeforeDelete 事件中。顺便说一句,标准的 TDBNavigator 有一个 ConfirmDelete 属性 与其集成的 DeleteRecord 按钮相关联,这将完全做到这一点,即向用户弹出确认提示。

更一般地说,人们经常通过尝试在数据集事件中执行不适合调用事件代码时数据集所处状态的操作来给自己制造问题。 TDataSet 有一个非常精心设计的操作逻辑流,对于没有经验或粗心的程序员来说,通过在 TDataSet 事件中做一些不应该存在的事情来颠覆它的逻辑是相当容易的:一个例子是在内部调用 Delete一个事件。另一个经常遇到的是执行代码,该代码将数据集的光标移动到一个事件中,该事件被称为移动光标的结果,例如 AfterScroll 事件,f.i.

没有简单的规则可以说明您在数据集事件中应该做什么和不应该做什么,但一般来说,您采取的任何试图更改数据集状态的操作 属性(请参阅 OLH 中的 TDataSetState ) 应该是您发现意外情况发生时的主要嫌疑人。

我假设另一个一般规则,除了 OLH 中事件描述中通常清楚的例外,数据集事件通常应该用于通过对其他对象执行某些操作来对事件做出反应,例如更新状态面板,而不是对数据集 做一些事情。 F.i。 AfterScroll 事件对于在移动数据集的光标时对更改做出反应非常有用。例外情况是像 BeforePost 这样的事件,它们旨在让您有机会做一些事情(例如验证对数据集字段的更改)。

顺便说一句,您可以从 BeforeDelete 事件中调用 Abort,它将阻止删除。但是,imo,检查删除是否应该继续并在 继续之前就其后果进行计划和编码比必须中途退出要干净整洁。所以,恕我直言,我不同意另一个答案。决定是否过桥的时间是在你开始之前,而不是在你已经过了一半的时候。 Ymmv,当然。

问题来对地方了。在删除之前询问是错误的,因为它会强制您在每次调用 Delete 时询问问题。如果用户不想删除,更正确的答案是在 OnBeforeDelete 中中止删除。