首页 > 解决方案 > TADOQuery - 编辑模式插入新记录而不是编辑

问题描述

我对 的行为感到困惑TADOQuery,让我们打电话吧Q。当我使用Q.Edit时,填充一些字段,然后Post,它最终实际上插入了一条新记录。

代码很简单,从对象中读取 ID:

Q.SQL.Text := 'select * from SomeTable where ID = :id';
Q.Parameters.ParamValues['id'] := MyObject.ID;
Q.Open;
try
  Q.Edit;
  try
    Q['SomeField']:= MyObject.SomeField;
  finally
    Q.Post;
  end;
finally
  Q.Close;
end;

令我惊讶的是,它决定插入一条新记录,而不是更新预期的记录。单步执行代码,紧随其后Q.Edit,查询实际上处于Insert模式。

我在这里做错了什么?

标签: sqldelphiado

解决方案


我认为记录这种行为的评论是不恰当的。文档没有明确说明(可能是因为作者从未想过这一点)是不能保证这种行为是确定性的。

几十年来,TDataSet.Edit 的内部结构几乎没有变化。这是西雅图版本:

procedure TDataSet.Edit;
begin
  if not (State in [dsEdit, dsInsert]) then
    if FRecordCount = 0 then Insert else
    begin
      CheckBrowseMode;
      CheckCanModify;
      DoBeforeEdit;
      CheckParentState;
      CheckOperation(InternalEdit, FOnEditError);
      GetCalcFields(ActiveBuffer);
      SetState(dsEdit);
      DataEvent(deRecordChange, 0);
      DoAfterEdit;
    end;
end;

现在,请注意if .. then ..FRecordCount 的值是基于 FRecordCount 的值,在 TDataSet 代码中的各个点,它被诸如 in 之类的代码强制具有给定的假定值(不同的 1、0 或其他值),SetBufferCount并且行为未记录完全没有。因此,经过反思,我认为 Jerry 可能正确地期望尝试编辑不存在的记录应该被视为错误条件,而不是通过默默地调用 Insert 来捏造,无论它是否记录在案。


推荐阅读