可以将对从TFDQuery克隆的TFDMemTable所做的更改发送回数据库吗?

时间:2017-02-06 02:25:57

标签: delphi firedac

使用Delphi 10 Seattle我尝试使用TFDQuery克隆TFDMemTable,并将TFDMemTable中所做的更改保留到数据库中。

可记忆的更改出现在查询中,但不会一直到数据库。如果我直接修改查询中的值,它们会保存在数据库中。

var
  query : TFDQuery;
  memtable : TFDMemTable;
begin
  { run TFDQuery }
  query := TFDQuery.Create(nil);
  query.SQL.Text := 'select * from employee';
  query.Open;

  { clone query into memtable }
  memtable := TFDMemTable.Create(nil);
  memtable.CloneCursor(query);

  { go to the same record in query and memtable }
  memtable.First;
  query.First;
  Assert(memtable.Fields[0].Value = query.Fields[0].Value);

  { edit the record in the memtable from ABC to XYZ }
  Assert(memtable['SomeField'] = 'ABC');
  memtable.Edit;
  memtable['SomeField'] := 'XYZ';
  memtable.Post;

  { verify record also changed in query }
  Assert(query['SomeField'] = 'XYZ');

  { has the change gone through to the database? }
  query.Close;
  query.Open;
  query.First;
  Assert(query['SomeField'] = 'XYZ');  // assertion fails, value is still ABC

1 个答案:

答案 0 :(得分:1)

有趣的q。我试着用MergeDataSet来填空。

但是,我想知道我是不是想吃太多的饭。 令我惊讶的是,以下工作找到了我,并且FDMemTable中所做的更改将持久保存回数据库(MS Sql Server 2014使用MS pubs数据库中的authors表,Delphi Seattle):

procedure TForm1.btnCopyToMemTableClick(Sender: TObject);
begin
  FDMemTable1.CloneCursor(FDQuery1);
end;

procedure TForm1.btnSaveBackClick(Sender: TObject);
var
  Errors : Integer;
begin
  Errors := FDQuery1.ApplyUpdates;
  FDQuery1.Close;
  //  need to close FDMemTable1 before re-opening FDQuery1, otherwise the
  //  call to FDQuery1 provokes a complaint about a duplicated column.
  FDMemTable1.Close;

  FDQuery1.Open;
  FDMemTable1.CloneCursor(FDQuery1);
end;

由此看来,在query.ApplyUpdates(0)关闭之前,您的代码似乎缺少query,并且在尝试重新打开memtable.close之前调用query以避免代码中注明的错误。

所以在这种情况下,KISS似乎适用,但我很想知道是否有办法使用MergeDataSet获得相同的结果。

顺便说一句,以下是您的代码的一个小变化,以使其适应我的测试平台:

var
  query : TFDQuery;
  memtable : TFDMemTable;
begin
  //  Using the MS pubs demo database
  query := FDQuery1;
  query.SQL.Text := 'select * from authors';
  query.CachedUpdates := True;
  query.Open;

  { clone query into memtable }
  memtable := FDMemTable1;
  memtable.CloneCursor(query);

  { go to the same record in query and memtable }
  memtable.First;
  query.First;
  Assert(memtable.Fields[0].Value = query.Fields[0].Value);

  { edit the record in the memtable from ABC to XYZ }
  //Assert(memtable[''] = 'ABC');
  memtable.Edit;
  memtable['Phone'] := '666';
  memtable.Post;

  { verify record also changed in query }
  Assert(query['Phone'] = '666');

  //  Added
  query.ApplyUpdates(0);
  { has the change gone through to the database? }
  query.Close;

  //  Added
  //  need to close memtable before re-opening query, otherwise the
  //  call to query provokes a complaint about a duplicated column.
  memtable.Close;

  query.Open;
  query.First;
  Assert(query['Phone'] = '666');  // assertion succeeds