是否可以将对从 TFDQuery 克隆的 TFDMemTable 所做的更改发送回数据库?
Can changes made to a TFDMemTable cloned from a TFDQuery be sent back to the database?
With Delphi 10 Seattle 我正在尝试用 TFDMemTable
克隆 TFDQuery
并将 TFDMemTable
中所做的更改保存到数据库中。
memtable 更改出现在查询中,但没有一直到数据库。如果我直接修改查询中的值,它们会保存在数据库中。
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
有趣的问题。我试图通过使用 MergeDataSet
.
来解决这个问题
然而,我想知道我是不是想把它做太多。
令我惊讶的是,我找到了以下作品,并且在 FDMemTable 中所做的更改被保存回数据库(MS Sql Server 2014 使用作者 table 在 MS pubs 数据库中,Delphi 西雅图):
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
关闭之前缺少 query.ApplyUpdates(0)
,并且在尝试 re-open [=14] 之前缺少对 memtable.close
的调用=] 以避免代码中指出的错误。
所以在这种情况下,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
With Delphi 10 Seattle 我正在尝试用 TFDMemTable
克隆 TFDQuery
并将 TFDMemTable
中所做的更改保存到数据库中。
memtable 更改出现在查询中,但没有一直到数据库。如果我直接修改查询中的值,它们会保存在数据库中。
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
有趣的问题。我试图通过使用 MergeDataSet
.
然而,我想知道我是不是想把它做太多。 令我惊讶的是,我找到了以下作品,并且在 FDMemTable 中所做的更改被保存回数据库(MS Sql Server 2014 使用作者 table 在 MS pubs 数据库中,Delphi 西雅图):
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
关闭之前缺少 query.ApplyUpdates(0)
,并且在尝试 re-open [=14] 之前缺少对 memtable.close
的调用=] 以避免代码中指出的错误。
所以在这种情况下,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