在现有TFDMemTable中添加字段后,通过TFDLocalSQL查询该表的任何TFDQuery都无法识别新字段。
下面的代码说明了这一点:在代码中添加了单个字段的TFDMemTable和在该表上执行select的TFDQuery。 (假设TFDMemTable被添加到TFDLocalSQL的DataSets属性,TFDQuery指向TFDConnection)将字段添加到实时TFDMemTable的过程来自example project和使用Unprepare,这看起来不像在这种情况下工作,来自这个question。
procedure TForm2.FormCreate(Sender: TObject);
begin
with FDMemTable1.FieldDefs.AddFieldDef do begin
Name := 'col1';
DataType := ftString;
Size := 10;
end;
FDMemTable1.CreateDataSet;
FDMemTable1.Active := true;
FDQuery1.SQL.Text := 'SELECT * FROM FDMemTable1';
FDConnection1.Connected := true;
FDLocalSQL1.Active := true;
FDQuery1.Active := true;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
tempMT: TFDMemTable;
begin
tempMT := TFDMemTable.Create(nil);
try
tempMT.Data := FDMemTable1.Data;
FDMemTable1.Close;
with FDMemTable1.FieldDefs.AddFieldDef do begin
Name := 'col99';
DataType := ftString;
Size := 10;
end;
FDMemTable1.Open;
FDMemTable1.MergeDataSet(tempMT, dmDataSet, mmNone);
if not FDMemTable1.FieldDefs.Updated then FDMemTable1.FieldDefs.Update;
finally
tempMT.Free;
FDQuery1.Active := false;
FDQuery1.Unprepare; // this is meant to uncache the fields
FDQuery1.Active := true; // Does not include 'col99' in result set
end;
end;
该字段肯定已添加到TFDMemTable并且工作正常。关于如何让TFDQuery识别新列的任何提示。
答案 0 :(得分:1)
我认为您获得此行为的原因是您的代码缺少一步。
在点击处理程序的finally
子句中,您需要关闭FDConnection,就像这样
finally
tempMT.Free;
FDConnection1.Connected := False;
FDQuery1.Active := false;
FDQuery1.Unprepare; // this is meant to uncache the fields
FDQuery1.Active := true; // Does include 'col99' in result set
Caption := IntToStr(FDQuery1.FieldCount);
end;
PageControl1.ActivePage := TabSheet3; // has FDQuery grid
完成上述更改后,您会发现在FDQuery1中获得了添加的列。顺便说一句,你可以拿出FDQuery.Unprepare
,因为它没有任何区别。 Prepare
通常用于编译后端数据库服务器内的查询的SQL代码。在这种情况下,不涉及后端服务器,因为FDLocalSQL1组件从mem表生成FDQuery1的数据。 Unprepare
通常告诉后端服务器它可以释放已编译的查询资源。
我认为你的版本不起作用的原因是因为调用了
中的GetActualActive
procedure TFDCustomLocalSQL.CheckActivate;
var
i: Integer;
begin
if GetActualActive and not FActivated then begin
for i := 0 to DataSets.Count - 1 do
DataSets.CheckUnique(DataSets[i]);
FActivated := True;
InternalAttachToSQL;
for i := 0 to DataSets.Count - 1 do
if DataSets[i].IsValid then
InternalDataSetAdded(DataSets[i]);
end;
end;
GetActualActive
定义为
function TFDCustomLocalSQL.GetActualActive: Boolean;
begin
Result := Active and (Connection <> nil) and Connection.Connected;
end;
因此,如果FDLocalSQL1之前处于活动状态,那么CheckActivate
的其余部分将被跳过,而且FDConnection已经连接了。因此,断开FDConnection允许CheckActivate
的内部执行,因此FDLocalSQL1“注意到”对FDMemTable1结构的更改。
顺便说一句,而不是从头开始编写代码,我将我的项目基于这个:
D:\ D10 \ Samples \ Object Pascal \ Database \ FireDAC \ Samples \ Comp Layer \ TFDLocalSQL \ InMemDB
避免了对项目设置方式的一定程度的猜测。