首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让TFDQuery识别新字段何时添加到正在通过TFDLocalSQL查询的TFDMemTable中

如何让TFDQuery识别新字段何时添加到正在通过TFDLocalSQL查询的TFDMemTable中
EN

Stack Overflow用户
提问于 2017-03-27 06:47:13
回答 1查看 1.5K关注 0票数 1

在将字段添加到现有的TFDMemTable之后,任何通过TFDLocalSQL查询该表的TFDQuery都不会识别新字段。

下面的代码说明了这一点:在代码中添加一个字段的TFDMemTable和在该表上进行选择的TFDQuery。(假设TFDMemTable被添加到TFDLocalSQL的DataSets属性中,TFDQuery指向TFDConnection)将字段添加到活动TFDMemTable的过程来自示例项目,Un准备的使用(在本例中似乎不起作用)来自于这个问题

代码语言:javascript
复制
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识别新专栏的任何技巧。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-27 12:57:07

我认为您之所以会出现这种行为,是因为您的代码错过了一步。

在单击处理程序的finally子句中,需要关闭FDConnection,如下所示

代码语言:javascript
复制
  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的调用

代码语言:javascript
复制
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被定义为

代码语言:javascript
复制
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

这避免了一定数量的猜测,你的项目是如何设置。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43039581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档