我很疑惑,在行为上。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
模式。
我可能在这里做错了什么?
我认为这种行为被记录的评论是不对的。 文档中记载的是 不要 清楚地表明(可能是因为作者从未想到这一点),这种行为并不能保证是确定性的。
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代码的不同点上,它被强制地具有一个给定的假设值(不同的是1,0或其他值),如在 SetBufferCount
和 该 行为没有记录 根本. 所以反思一下,我觉得Jerry的期望可能是对的,试图编辑一个不存在的记录应该被当作错误条件,而不是通过默默调用Insert是否有记录来搪塞。
我既发问题又发答案,因为问题的原因是完全出乎意料的行为,肯定有人也发生了同样令人费解的事情。
这种情况发生在你试图编辑的数据集没有任何记录的情况下。我个人认为应该产生一个异常,当没有记录时,你不能编辑。但是 TADOQuery
决定追加一条新记录。
这个问题的根本原因是,我提供了对象的 ID
实际价值为 0
因此,由于数据库中没有ID为0的记录,所以什么也没有返回。