在将字段添加到现有的TFDMemTable之后,任何通过TFDLocalSQL查询该表的TFDQuery都不会识别新字段。
下面的代码说明了这一点:在代码中添加一个字段的TFDMemTable和在该表上进行选择的TFDQuery。(假设TFDMemTable被添加到TFDLocalSQL的DataSets属性中,TFDQuery指向TFDConnection)将字段添加到活动TFDMemTable的过程来自示例项目,Un准备的使用(在本例中似乎不起作用)来自于这个问题。
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识别新专栏的任何技巧。
发布于 2017-03-27 12:57:07
我认为您之所以会出现这种行为,是因为您的代码错过了一步。
在单击处理程序的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通常用于编译后端DB服务器内部查询的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;因此,如果CheckActivate的其他部分以前是活动的,并且FDConnection已经连接到了,那么就跳过了。因此,断开FDConnection允许执行CheckActivate的内部,因此FDLocalSQL1“注意”了对FDMemTable1结构的更改。
顺便说一句,我是从零开始编写代码的,我的项目是基于这个:
D:\D10\Sample\Object Pascal\Database\FireDAC\Samples\Comp Layer\TFDLocalSQL\InMemDB
这避免了一定数量的猜测,你的项目是如何设置。
https://stackoverflow.com/questions/43039581
复制相似问题