TADOQuery - 编辑模式插入新记录而不是编辑

Jer*_*dge 7 sql delphi ado

我对 的行为感到困惑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;
Run Code Online (Sandbox Code Playgroud)

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

我在这里做错了什么?

Mar*_*ynA 5

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

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;
Run Code Online (Sandbox Code Playgroud)

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