Database 如何在运行时向clientdataset添加字段?

Database 如何在运行时向clientdataset添加字段?,database,delphi,dataset,tclientdataset,Database,Delphi,Dataset,Tclientdataset,我有一个TClientDataSet,它由TTable的数据集提供。 数据集有两个字段:postalcode(字符串,5)和street(字符串,20) 在运行时,我想显示第三个字段(字符串,20)。此字段的例程获取postalcode作为参数,并返回属于此postalcode的城市 问题只是将计算字段添加到现有字段中。填充数据本身不是问题 我试过: cds.SetProvider(Table1); cds.FieldDefs.Add('city', ftString, 20);

我有一个
TClientDataSet
,它由
TTable
的数据集提供。 数据集有两个字段:postalcode(字符串,5)和street(字符串,20)

在运行时,我想显示第三个字段(字符串,20)。此字段的例程获取postalcode作为参数,并返回属于此postalcode的城市

问题只是将计算字段添加到现有字段中。填充数据本身不是问题

我试过:

  cds.SetProvider(Table1);
  cds.FieldDefs.Add('city', ftString, 20);

  cds.Open;

  cds.Edit;
  cds.FieldByName('city').AsString := 'Test';  // --> errormessage (field not found)
  cds.Post;
cds是我的clientdataset,
Table1
是一个悖论表,但其他数据库的问题也是如此


提前感谢

如果要添加基础数据中存在的字段以外的其他字段,还需要手动添加现有字段。添加字段时需要关闭数据集,但如果不想手动跟踪所有字段详细信息,可以使用
FieldDefs.Update
获得必要的元数据。基本上是这样的:

var
  i: Integer;
  Field: TField;
begin    
  cds.SetProvider(Table1);

  // add existing fields
  cds.FieldDefs.Update;
  for i := 0 to cds.FieldDefs.Count - 1 do 
    cds.FieldDefs[i].CreateField(cds);

  // add calculated field
  Field := TStringField.Create(cds);
  Field.FieldName := 'city';
  Field.Calculated := True;
  Field.DataSet := cds;

  cds.Open;
end;


另请参见。

我找到了一个更简单的解决方案,因为我的sql中有24个字段,我不想手动添加所有字段,所以我在sql语句中添加了一个虚拟字段,如下所示:

select '      ' as city, the rest of the fields ... 
我可以在打开事件后在程序中修改它


我必须在sql中定义该字段的长度,方法是留出足够的空格,例如5个空格容纳5个字符,因此我必须知道城市名称的长度。

如果您想将现有的“动态”数据字段(来自提供者端)与其他客户端持久字段相结合(计算、查找、内部计算、聚合)您应该为CDS创建子类。只需引入额外的布尔属性CombineFields,并用以下行覆盖BindFields(在较新的delphi版本中)或整个InternalOpen(如我在d2006/2007中所做的)

如果DefaultFields或CombineFields,则CreateFields;{TODO-ovavan-cSIC:如果CombineFields为true,则持久性字段将与默认字段共存}


这将允许您避免FieldDefs/CreateField的运行时混乱。您希望共享对不存在字段的更精确查询。我打赌最好使用cast,而不是空格

select E.NAME, E.SURNAME, cast(null as varchar(20)) as CITY
from EMPLOYEE E
e、 g.
|马克·奥|波罗|


它更准确,可以明确地看到字段大小,易懂、简单、安全!

添加字段后,您应该使用
CreateDataset

cds.SetProvider(Table1);
cds.FieldDefs.Add('city', ftString, 20);
cds.CreateDataset; 

cds.Open;
cds.Edit;
cds.FieldByName('city').AsString := 'Test';  
cds.Post;

与我的感谢您的回答和漂亮的链接类似,我会尝试这个,尽管我必须手动添加我的sql中的所有文件。这看起来可能并不优雅,但它确实很容易实现。