首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加载现有数据时向FDMemTable添加新字段

加载现有数据时向FDMemTable添加新字段
EN

Stack Overflow用户
提问于 2017-07-02 19:54:37
回答 2查看 8K关注 0票数 0

我使用的是TFDMemTable,我创建了一个数据集并用数据填充了我的表,然后使用FDMemTable.saveToFile保存数据。

下面是一个问题,我如何在这个已经保存的数据中添加一个新的Field,并用默认值填充所有记录?

我试着将新的Field添加到FDMemTable中,然后加载信息,希望它能够使用它的FieldName和新字段来填充每个字段,但是我发现了一个错误:‘?“??”?

调试器异常通知

Project1.exe引发异常类EDatabaseError,其消息为“字段”Episode“not”。

中断继续帮助

`

我怎么才能解决这个问题?是否需要在现有数据中添加一个默认值的新字段?

下面是一个测试案例:

代码语言:javascript
复制
// here is a simple example, i have a few fields
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

FDMemTable1.CreateDataSet;

// i fill the the table with some value
FDMemTable1.Open;
FDMemTable1.AppendRecord([1, 'Movie1', 1]);
FDMemTable1.AppendRecord([2, 'Movie2', 2]);
FDMemTable1.AppendRecord([3, 'Movie3', 1]);

// after seeing the value on the grid, i push a button and save the table as XML
FDMemTable1.saveToFile('Data.xml');

// now after closing the program and running it again, i want to load the data with a new FieldDef Called Episode with a default value 0
// the table is connected to cxGrid, and the moment i try to load, i get the error i mentioned.

FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
// this line is NEW
FDMemTable1.FieldDefs.Add('Episode', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

FDMemTable1.CreateDataSet;

// i try to load but i get an error
FDMemTable1.loadFromFile('Data.xml');

更新1(基于维多利亚的回答) :

代码语言:javascript
复制
//All the codes below are executed after the code at the top, after the loadFromFile.
  FDMemTable1.ResourceOptions.StoreItems := FDMemTable1.ResourceOptions.StoreItems + [siMeta];
  FDMemTable1.Close;

  //i tried putting FDMemTable1 as the owner but when i try the line "FDMemTable1.Fields.add" i get an Duplicate error!
  // and when i try putting nil, i get access violation ! so i tried putting the owner someother random table and it fixed the problem
  fieldDefs := TFieldDefs.Create(someRandomFDMemTable);
  fieldDefs.Add('Episodes', ftString, 30, false);

  FDMemTable1.Fields.Add(fieldDefs.Items[0].CreateField(FDMemTable1));
  FDMemTable1.Open;

你看,我有两个问题,

我在添加一个新字段时遇到了问题!在我遇到错误的地方,我首先尝试使用TFieldDef而不是TFieldDefs,但是我无法让它工作。

2-是这样一个事实,即所有列都是空的,而且网格上没有数据。

当我试图有力地解决问题1时,问题2就会发生。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-08 09:24:33

下面的代码对我来说很好,在德尔菲西雅图。它是基于你的,但有一些小的变化(见评论)和一个重要的补充。

问题是,如果您仔细观察FDMemTable1.loadFromFile,它实际上清除了FieldDefs/ field,所以在第一次设置它们时没有太多的意义,所以您添加的Episode字段将被从加载的数据集中省略。

为了避免这种情况,我添加了一个临时TFDMemTable,将XML文件加载到其中,然后使用CopyDataSet将其内容复制到FDMemTable1中。FDMemTable1在这个过程中保留了新增的Episode字段,当然您可以添加代码来在调用CopyDataSet之后设置Episode字段数据。

代码语言:javascript
复制
procedure TForm1.AddFieldTest;
var
  DataFN : String;
  TempMemTable : TFDMemTable;
begin
  // Added, to avoid relative path for data file name
  DataFN := ExtractFilePath(Application.ExeName) + 'Data.Xml';

  FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
  FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

  FDMemTable1.CreateDataSet;

  // i fill the the table with some value
  FDMemTable1.Open;
  FDMemTable1.AppendRecord([1, 'Movie1', 1]);
  FDMemTable1.AppendRecord([2, 'Movie2', 2]);
  FDMemTable1.AppendRecord([3, 'Movie3', 1]);

  // after seeing the value on the grid, i push a button and save the table as XML
  FDMemTable1.saveToFile(DataFN);

  // Added, close the dataset and clear the FieldDefs
  // Without the FieldDefs.Clear call, your code produces a "Duplicate field ID" error 
  FDMemTable1.Close;
  FDMemTable1.FieldDefs.Clear;

  // now after closing the program and running it again, i want to load the data with a new FieldDef Called Episode with a default value 0
  // the table is connected to cxGrid, and the moment i try to load, i get the error i mentioned.

  FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
  // this line is NEW
  FDMemTable1.FieldDefs.Add('Episode', ftInteger, 0, false);
  FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);

  FDMemTable1.CreateDataSet;

  // check the FieldCount and existence of the Episode field
  Caption := IntToStr(FDMemTable1.FieldCount);
  Assert(FDMemTable1.FindField('Episode') <> Nil);

  //  Create a temporary TFDMemTable
  TempMemTable := TFDMemTable.Create(Nil);
  try
    //  load the data into the temporary TFDMemTable
    TempMemTable.loadFromFile(DataFN);
    //  copy the data from the temporary TFDMemTable into FDMemTable1
    FDMemTable1.CopyDataSet(TempMemTable, [coAppend]);

  // check the FieldCount and existence of the Episode field
    Caption := IntToStr(FDMemTable1.FieldCount);
    Assert(FDMemTable1.FindField('Episode') <> Nil);
  finally
    TempMemTable.Free;
  end;
end;
票数 5
EN

Stack Overflow用户

发布于 2017-07-03 22:44:06

在从文件加载数据集后添加该字段(而不是字段定义)(假设siMeta包含在TFDMemTableResourceOptionsStoreItems属性中)。请注意,必须在将字段添加到字段集合时关闭dataset。

因此,在从文件加载后立即关闭数据集,添加该字段并再次打开它。

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

https://stackoverflow.com/questions/44874674

复制
相关文章

相似问题

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