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

vwoqyblh  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(249)

我对这个人的行为感到困惑 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 模式。
我会做错什么?

dnph8jn4

dnph8jn41#

我发布了一个问题和一个答案,因为问题的原因是完全出乎意料的行为,肯定有其他人也发生了同样令人困惑的事情。
如果您试图编辑的数据集没有任何记录,则会发生这种情况。就我个人而言,我认为它应该产生一个例外,当没有记录时,你不能编辑它。但是 TADOQuery 决定附加一个新记录。
这个问题的根本原因是我提供 ID 实际价值是 0 ,因此,由于数据库中没有id为0的记录,因此它没有返回任何内容。

x6yk4ghg

x6yk4ghg2#

我认为这种行为被记录在案的评论是离题的。文档没有明确说明的是(可能是因为作者从未想到这一点)这种行为不能保证是确定性的。
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的值为基础的,在tdataset代码的不同点上,它被代码(如in)强制具有给定的假定值(不同的是1、0或其他值) SetBufferCount 这种行为根本没有记录在案。因此,经过思考,我认为jerry认为,试图编辑一个不存在的记录应该被视为一个错误条件,而不是通过无提示地调用insert(不管它是否有文档记录)来敷衍。

相关问题