You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.1中ADOQuery编辑DBF数据库出现更新行找不到错误求助

Delphi 10.1中ADOQuery编辑DBF记录Post报错问题

问题现象

在Delphi 10.1中使用ADOQuery的Edit和Post方法编辑DBF数据库记录时,调用ADOQuery.Post时出现错误:

指定用于更新的行未找到。自上次读取后部分值可能已更改

编辑操作在打开的第二个窗体中进行,通过属性传递TADOConnection、TDataSource和TADOQuery对象,需求是选中DBGrid中的单元格后点击编辑按钮修改其内容。

相关代码

公共属性定义

public
  { Public-Deklarationen }
  selectedRow, selectedCol : Integer;
  property ADOConnection : TADOConnection read FADOConnection write FADOConnection;
  property ADOQuery : TADOQuery read FADOQuery write FADOQuery;
  property DataSource : TDataSource read FDataSource Write FDataSource;
end;

DBGrid单元格点击事件

procedure TForm3.DBGrid1CellClick(Column: TColumn);
begin
  selectedCol := DBGrid1.SelectedField.Index;
  selectedRow := DBGrid1.DataSource.DataSet.RecNo;
end;

编辑按钮点击事件

procedure TForm3.BtnEditClick(Sender: TObject);
var
  iReplacement : string;
begin
  iReplacement := InputBox('Wert', 'Ändere den Wert "' + DBGrid1.Columns[selectedCol].Field.FieldName +  '" für: ' + ADOQuery.Fields[0].AsString + ', ' + ADOQuery.Fields[2].AsString, ADOQuery.Fields[selectedCol].AsString);
  try
    ADOQuery.Edit;
    ADOQuery[DBGrid1.Columns[selectedCol].Field.FieldName] :=  iReplacement;
    ADOQuery.Post;
    //ADOQuery.Refresh;
  except on E: Exception do
    MessageDlg('Error: ' + E.Message, mtError, [mbOk], 0);
  end;
end;

简化测试代码(仍报错)

ADOQuery1.Edit;
ADOQuery1BEZEICHNG.Value := 'Hello';
ADOQuery1.Post;

补充信息

  • ADOConnection连接字符串:
    Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="CollatingSequence=ASCII;DefaultDir=J:\ROBERT\DATABASE;Deleted=0;Driver={Microsoft dBase-Treiber (*.dbf)};DriverId=277;FIL=dBase IV;FILEDSN=C:\Users\User\Documents\ABzuFA.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Statistics=0;Threads=3;UID=admin;UserCommitSync=Yes;";Initial Catalog=J:\ROBERT\DATABASE
    
  • 加载数据的SQL语句:Select * from Orders
  • 测试情况:在另一小型DBF数据库上运行相同代码可正常编辑,仅目标数据库出现该问题

解决方案

1. 给DBF表添加主键/唯一索引

DBF驱动更新记录时需要唯一标识定位行,若表无主键或唯一索引,驱动无法精准匹配要更新的行。给Orders表添加主键(如订单ID类唯一字段)或唯一索引。

2. 调整连接字符串参数

在连接字符串的Extended Properties中添加Exclusive=1,以独占模式打开数据库,避免其他进程同时修改数据导致行版本不一致:

Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="CollatingSequence=ASCII;DefaultDir=J:\ROBERT\DATABASE;Deleted=0;Driver={Microsoft dBase-Treiber (*.dbf)};DriverId=277;FIL=dBase IV;FILEDSN=C:\Users\User\Documents\ABzuFA.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Statistics=0;Threads=3;UID=admin;UserCommitSync=Yes;Exclusive=1;";Initial Catalog=J:\ROBERT\DATABASE

3. 显式通过主键定位记录

避免依赖RecNo定位行,改用主键字段重新定位后再编辑:

procedure TForm3.BtnEditClick(Sender: TObject);
var
  iReplacement : string;
  PrimaryKeyValue: Variant;
begin
  // 假设主键为第一个字段,根据实际表结构调整
  PrimaryKeyValue := ADOQuery.Fields[0].Value;
  iReplacement := InputBox('值', '修改字段 "' + DBGrid1.Columns[selectedCol].Field.FieldName + '" 的值:' + ADOQuery.Fields[0].AsString + ', ' + ADOQuery.Fields[2].AsString, ADOQuery.Fields[selectedCol].AsString);
  try
    // 重新定位到目标记录
    ADOQuery.Locate(ADOQuery.Fields[0].FieldName, PrimaryKeyValue, []);
    ADOQuery.Edit;
    ADOQuery[DBGrid1.Columns[selectedCol].Field.FieldName] := iReplacement;
    ADOQuery.Post;
  except on E: Exception do
    MessageDlg('错误: ' + E.Message, mtError, [mbOk], 0);
  end;
end;

4. 检查并修复DBF表损坏

使用DBF专用修复工具(如dBase自带工具或第三方工具)检查Orders.dbf,若表结构或数据存在损坏,修复后再尝试更新。

5. 更换DBF访问组件

尝试使用Borland原生TDBF组件替代ADO连接,部分情况下原生组件对旧版DBF格式的兼容性更好。


内容的提问来源于stack exchange,提问作者Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:15:57