如何在运行时更改Clientdataset字段数据类型

时间:2014-10-30 21:41:07

标签: database delphi dataset tclientdataset

对于已在设计时定义字段的Delphi ClientDataSets,在运行时是否有办法更改特定字段的数据类型(更改cds.Fields [n] .DataType)?

我有一个遗留的Delphi 7程序,在设计时设置了SQLDataSet和ClientDataSet字段(为了覆盖各种属性)。

它们连接到第三方Sybase SQL Anywhere 11数据库。

最近,该供应商更改了所有'描述'从VarChar(128)到long varchar的字段,但仅限于他的某些客户。因此,当我查询这些'描述'时,我的代码必须支持这两种类型的字段。字段。

我希望在类字段类型上设置条件编译(然后在打开SQL / CLient数据集之前添加字段),但编译器忽略类的组件定义部分中的{$ IFDEF}条件(其中,我想的更多,很有道理)!

有数十个模块,有数百个字段受到影响,所以我们非常感谢任何见解。

1 个答案:

答案 0 :(得分:1)

我之前也遇到过这个问题,不是用CDS,而是在设计时使用持久字段的TADODataSet。我认为下面的代码将帮助您了解如何修复/修补CDS数据集。

这个想法是查询相关的表模式;获取实际的fileds数据类型;并通过从DataSet取消附加并添加新的匹配持久字段来“更改”持久字段类型:

// TData class    
procedure TData.DataModuleCreate(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ComponentCount - 1 do
    if (Components[I] is TCustomADODataSet) then
      DataSetPrepareMemoFields(TDataSet(Components[I]));
end;

procedure TData.DataSetPrepareMemoFields(DataSet: TDataSet);
var
  Fld: TField;
  I: Integer;
  FldName, CompName: string;
  AOwner: TComponent;
begin
  // Here you need to query the actual table schema from the database 
  // e.g. ADOConnection.GetFieldNames and act accordingly

  // check which DataSet you need to change
  // if (DataSet = dsOrders) or ... then... 

  if DataSet.FieldList.Count > 0 then
    for I := DataSet.FieldList.Count - 1 downto 0 do 
    begin
      if DataSet.FieldList.Fields[I].ClassNameIs('TMemoField') and (DataSet.FieldList.Fields[I].FieldKind = fkData) then 
      begin
        // save TMemoField properties
        AOwner := DataSet.FieldList[I].Owner;
        CompName := DataSet.FieldList[I].Name;
        FldName := DataSet.FieldList.Fields[I].FieldName;
        // dispose of TMemoField
        DataSet.FieldList[I].DataSet := nil; // Un-Attach it from the DataSet
        // create TWideADOMemoField instead
        Fld := TWideADOMemoField.Create(AOwner); // Create new persistent Filed instead 
        Fld.Name := CompName + '_W';
        Fld.FieldName := FldName;
        Fld.DataSet := DataSet;
      end;
    end;
end;

那就是说,在我解决了这个问题之后,我再也没有使用过持久字段了。 我的所有字段都是在运行时生成的。包括计算/查找/内部字段。