在一个表单上,我有一个 Quantum Grid 和一些支持 db 的编辑组件。在网格中添加新记录时,在网格和单独的编辑组件中键入一些编辑值,我收到一个错误:
EOleException:无法找到要更新的行。自上次读取以来,某些值可能已更改
经过一番谷歌搜索,我认为将“更新标准”属性从 adCriteriaAllCols 更改为 adCriteriaKey 可能是正确的解决方案。但是,我如何以及何时在 Adonis 查询中执行此操作?
如果您的数据集包含自动增量字段或一个或多个字段具有默认值,那么这可能是问题所在。调用 Post 字段后,更改它们在数据库中的值,但您的数据集可能无法检测到
虽然我不使用 Adonis,但我相信它有可能使用 TClientDataset (CDS) 用来识别构成主键的字段的相同机制:属性TField.ProviderFlags。
我相信这可能是一个开始寻找的好地方。
实际上 ADO 提供了动态属性来控制基于查询的更新 (QBU) 行为 大多数代码都包含在 ADOInt.pas 中,相应的事件是记录集属性(任何 TADODataSet)的 OnAfterOpen 和连接属性(TADOConnection)的 OnCreate。我猜“更新标准”不是这种情况下的解决方案,因为它处理 WHERE 子句来指定用于更新的字段。您可以按如下方式更改“更新重新同步”:
//After open a TCustomADODataSet
TCustomADODataSet(DataSet).Properties['Update Resync'].Value :=
adResyncAutoIncrement + adResyncUpdates + adResyncInserts;
如果您的查询中有连接表:
TADOQuery 不能在 sql 数据库中编辑和发布数据。
您可以创建其他 TADOQuery 并通过主键选择而无需任何连接表并编辑然后将数据发布到 sql 数据库中。
我遇到了类似的问题 - 更新所有值都相同的行会导致您遇到错误。我在 ado 连接的末尾添加了标志“Option=2”,这解决了问题。
这是旧的。但我的情况可能发生在别人身上。所以我发布了这个答案。
这个错误也发生在我身上。我正在使用 Access 数据库并在表单上使用一些 TADOTable。关系是主从关系,我将所有表与 IDE 设计器连接在一起。我的桌子是 tbl_Floor、tbl_FloorParts、tbl_Seat,其中 tbl_Floor 是 tbl_FloorParts 的主人,而 tbl_FloorParts 是 tbl_Seat 的主人。所以为了解决这个错误,我做了这个技巧。
procedure Tfrm_Main.UpdateTblFloor(...);
var
FID:Integer;
q:TADOQuery
begin
FID:=tbl_Floor.FieldByName('FID').AsInteger;
tbl_Floor.Close;
q:=TADOQuery.Create(nil);
try
q.Connection:=tbl_Floor.Connection;
q.SQL.Add('Update [Floor]');
q.SQL.Add(...);//Set Fields that needed to be updated
q.SQL.Add('where [FID]='+IntToStr(FID));
q.ExecSQL;
finally
q.free;
end;
tbl_Floor.Open;
tbl_Floor.Locate('FID',FId,[loPartialKey]);
end;
我为 tbl_Floor,tbl_FloorParts 添加了这些事件
procedure Tfrm_Main.tbl_FloorAfterOpen(DataSet: TDataSet);
begin
tbl_FloorParts.Open;
end;
procedure Tfrm_Main.tbl_FloorBeforeClose(DataSet: TDataSet);
begin
tbl_FloorParts.Close;
end;
procedure Tfrm_Main.tbl_FloorPartsAfterOpen(DataSet: TDataSet);
begin
tbl_Seat.Open;
end;
procedure Tfrm_Main.tbl_FloorPartsBeforeClose(DataSet: TDataSet);
begin
tbl_Seat.Close;
end;