首页 > 解决方案 > 为什么此代码在第二次单击按钮中不起作用

问题描述

我为按钮单击事件编写此代码。我第一次单击按钮时,一切正常,但是当第二次单击按钮时,它会引发错误。有什么问题?

procedure TfrmMain.Button1Click(Sender: TObject);
var
  B : Boolean;
begin
  DM.tblTemp.DisableControls;
  B:= DM.tblTemp.Locate('FoodName', DM.tblAsli.FieldByName('FoodName').AsString,[]) ;
  if  B then
  begin
    DM.tblTemp.Edit;
    DM.tblTemp.FieldByName('Number').AsInteger:=  DM.tblTemp.FieldByName('Number').AsInteger + 1;
    DM.tblTemp.Post;
  end
  else
  begin
    DM.tblTemp.insert;
    DM.tblTemp.FieldByName('FoodName').AsString := DM.tblAsli.FieldByName('FoodName').AsString;
    DM.tblTemp.FieldByName('UnitPrice').AsInteger := DM.tblAsli.FieldByName('FoodPrice').AsInteger;
    DM.tblTemp.FieldByName('Number').AsInteger := 1;
    DM.tblTemp.Post;
  end;
  TotalPrice:= TotalPrice + DM.tblTemp.FieldByName('TotalPrice').AsInteger;
  DM.tblTemp.EnableControls;
end;

错误是

无法找到要更新的行。自上次读取以来,某些值可能已更改

DM 是数据 madual tmbTbl 是 ADOTable

标签: delphi

解决方案


很遗憾您没有说明您使用的是哪个 DBMS(例如 Sql Server 或 MS Access,也没有告诉我们表的列类型和索引的完整列表(如果有)。

您的 q 最可能的答案是变量 B 第一次设置为 False 因为对 tblTemp.Locate 的调用未能找到有问题的食物名称,因此执行插入分支并将食物的数据添加到表中但是第二次执行 Edit 分支并发生错误,尽管您没有确切地说出在哪里。我的猜测是调用 .Post,因为错误消息是 ADO 层之一,它位于 DBMS 提供程序和您的应用程序之间,当它尝试将更改发布到表但无法识别要更新的表行时发出. 正如我在评论中提到的,解决此问题的方法通常是向表中添加主键索引,我从您的最新评论中得知这对您来说已经成功。

Fwiw,我已经使用 MS Sql Server 和 MS Access 上的表测试了您的代码,并且没有得到任何数据库的错误。

顺便说一句,有一个明显的问题,“tblTemp.Locate 怎么会成功,但 ADO 无法识别正确的记录来发布更新?” 答案是 tblTemp.Locate 的工作方式与识别相关行以发布更新不同。


推荐阅读