sql - 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
模式。
我在这里做错了什么?
解决方案
我认为记录这种行为的评论是不恰当的。文档没有明确说明(可能是因为作者从未想过这一点)是不能保证这种行为是确定性的。
几十年来,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 来捏造,无论它是否记录在案。
推荐阅读
- sql - 如何使用 Haskell 中的 Beam 库编写返回嵌套列表的查询?
- c# - 如何对通过启动多个实例来旋转线程的内置 c# 程序 (program.exe) 进行压力测试
- reactjs - 如何更改 formcontrollabel 的默认排版类 - material-ui | 反应?
- python-2.7 - 为什么可执行文件会停止在 python 中使用 popen
- php - 如何替换 PHP 中的某些文本,而中间的文本不会影响进程
- jquery - 更改文本但不更改按钮内的图标
- c# - 如何使用 XElement 在 C# 中读取 xml?
- javascript - 无效的付款意图
- android - 如何使用tinymce删除Android中的灰色覆盖
- c# - 访问 C# 中的每个类元素