Delphi - ADOTable 没有正确删除记录并创建了幻影记录

Delphi - ADOTable does not delete records properly and creates ghost records

我需要帮助解决我的数据库问题。我有一个包含汽车记录的 .mdb 文件。这链接到我的 ADOTable,然后链接到 Delphi 中的 DBGrid。当我通过表单上的按钮删除记录时,它似乎没有正确删除它,因为当我滚动 dbgrid 时,活动记录假设为 change/update (取决于我是向下还是向上滚动) 并在 DBGrid 下面的编辑中显示活动记录的每个字段的值。

在我的代码删除记录后,当我在 MS Access 中查看它时,它没有出现在 DBGrid 或 .mdb 文件中,所以我认为它已被正确删除。但是,就像我上面解释的那样,当 OnMouseWheel 事件执行时,它会显示我猜是删除的记录,或者以前记录的数据DBGrid 活动记录的指针清楚地表明它应该显示下一条或上一条记录数据。

有趣的是,OnCellClick 和 DBGridNavigator 按钮对 DBGrid 和显示的记录信息没有这种影响。

图片:

在 OnMouseWheel 事件之前

每张图片执行1次后:

实际 .mdb 文件的图像:


使用的过程和函数代码:

OnMouseWheel:

procedure TCars.DBGrid1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; 
MousePos: TPoint; var Handled: Boolean);
begin
  Show_Car_Details;
end;

OnCellClick:

procedure TCars.DBGrid1CellClick(Column: TColumn);
begin
  Show_Car_Details;
end;

Show_Car_Details:

procedure TCars.Show_Car_Details;
begin
  with CarOwners.tbl_Cars do
  begin
    edt_Car_ID.text := inttostr(fieldbyname('ID').value);
    edt_Car_Type.text := fieldbyname('Make').value;
    edt_Car_Price.text := FloatToStr(fieldbyname('Price').value);
    edt_Car_Distance.text := inttostr(fieldbyname('Distance').value);
    edt_Owner_ID.text := inttostr(fieldbyname('OwnerID').value);

    if fieldbyname('Insurance').value = true then
    begin
      cbx_Insurance.ItemIndex := 0;
    end
    else
    begin
      cbx_Insurance.ItemIndex := 1;
    end;
  end;
end;

删除程序:

procedure TCars.bit_DeleteClick(Sender: TObject);
begin
  if messagedlg
    ('Are you sure you want to delete this record? It will permanently be removed.',
    mtConfirmation, [mbyes, mbno], 0) <> mryes then
    exit;

  CarOwners.tbl_Cars.Delete;
  DBGrid1.DataSource.DataSet.Refresh;
end;

以防万一,添加和更新程序的代码: 添加:

procedure TCars.bit_AddClick(Sender: TObject);
var
  Make: string;
  OwnerID, Distance: Integer;
  Price: real;
  Insurance: Boolean;
begin
  Make := edt_Car_Type.text;
  OwnerID := strtoint(edt_Owner_ID.text);
  Distance := strtoint(edt_Car_Distance.text);
  Price := strtofloat(edt_Car_Price.text);
  if cbx_Insurance.ItemIndex = 0 then
  begin
    Insurance := true;
  end
  else
  begin
    Insurance := false;
  end;

  Add_Record(Make, OwnerID, Price, Distance, Insurance);
end;
//---------------------------------------------------------
procedure TCars.Add_Record(Make: string; OwnerID: Integer; Price: real;
  Distance: Integer; Insurance: Boolean);
begin

  // ----validation----
  //validation done here(removed for space, just basic if with exit.)

  // add new information
  with CarOwners do
  begin
    tbl_Cars.DisableControls;
    tbl_Cars.last;
    tbl_Cars.Insert;
    tbl_Cars['Make'] := Make;
    tbl_Cars['OwnerID'] := OwnerID;
    tbl_Cars['Price'] := Price;
    tbl_Cars['distance'] := Distance;
    tbl_Cars['Insurance'] := Insurance;
    tbl_Cars.post;
    tbl_Cars.EnableControls;
  end;
end;

更新程序:

procedure TCars.bit_UpdateClick(Sender: TObject);
var
  Brand: string;
  Price: real;
  Insurance: Boolean;
  OwnerID, Distance: Integer;
begin
  Brand := edt_Car_Type.text;
  Price := strtofloat(edt_Car_Price.text);
  OwnerID := strtoint(edt_Owner_ID.text);
  Distance := strtoint(edt_Car_Distance.text);

  if cbx_Insurance.ItemIndex = 0 then
  begin
    Insurance := true;
  end
  else
  begin
    Insurance := false;
  end;

  Update_Record(Brand, OwnerID, Price, Distance, Insurance);
end;
//------------------------------------------------------------
procedure TCars.Update_Record(Make: string; OwnerID: Integer; Price: real;
  Distance: Integer; Insurance: Boolean);
begin
  //validation done here(removed for space, just basic if with exit.)

  // ----Update Information ----
  with CarOwners do
  begin
    tbl_Cars.DisableControls;
    tbl_Cars.edit;
    tbl_Cars['Make'] := Make;
    tbl_Cars['OwnerID'] := OwnerID;
    tbl_Cars['Price'] := Price;
    tbl_Cars['Distance'] := Distance;

    if Insurance then
    begin
      tbl_Cars['Insurance'] := true;
    end
    else
    begin
      tbl_Cars['Insurance'] := false;
    end;
    // ShowMessage('Posting...');
    tbl_Cars.post;
    // ShowMessage('Done');
    tbl_Cars.EnableControls;
  end;
end;

欢迎任何建议或帮助!!! 此致

感谢@MartynA 和@Olivier 的回答。问题是使用了错误的事件处理程序来刷新和显示记录的字段值。

请勿使用: OnMouseWheel

使用:

procedure TCarOwners.ds_CarsDataChange(Sender: TObject; Field: TField);
begin
  if Field = nil then
  begin
    Cars.show_car_details;
  end;
end;

这会正确更新非 data-aware 控件。请务必将 Form1 或我的 Cars_frm 添加到 implementation 下的 uses 列表中。