在运行时将计算字段添加到Query

Jam*_*ass 9 delphi calculated-field

我在Delphi中使用查询获取数据,并希望在运行之前向查询添加计算字段.计算字段使用代码中的值以及查询,因此我无法在SQL中计算它.

我知道我可以附加一个OnCalcFields事件来实际进行计算,但问题是在添加计算字段后查询中没有其他字段...

我做了一些挖掘,发现所有的场定义都是创建的,但实际的字段只是创建了

if DefaultFields then
    CreateFields
Run Code Online (Sandbox Code Playgroud)

指定了默认字段

procedure TDataSet.DoInternalOpen;
begin
    FDefaultFields := FieldCount = 0;
    ...
end;
Run Code Online (Sandbox Code Playgroud)

这表示如果添加字段,则只会获得您添加的字段.

我希望查询中的所有字段与我添加的字段一样好.

这是可能的还是我必须添加我正在使用的所有字段?

Fra*_*ois 12

没有什么可以阻止您在代码中首先创建所有字段,
然后添加计算字段.

您可以使用"黑客类型"来使用受保护的CreateField:

type
  THackQuery = class(TADOQuery)
  end;
[...]
  MyQuery.FieldDefs.Update;
  THackQuery(MyQuery).CreateFields;
Run Code Online (Sandbox Code Playgroud)

或者从CreateFields借用一些代码:

  MyQuery.FieldDefs.Update;
  // create all defaults fields
  for I := 0 to MyQuery.FieldDefList.Count - 1 do
    with MyQuery.FieldDefList[I] do
      if (DataType <> ftUnknown) and not (DataType in ObjectFieldTypes) and
        not ((faHiddenCol in Attributes) and not MyQuery.FIeldDefs.HiddenFields) then
        CreateField(Self, nil, MyQuery.FieldDefList.Strings[I]);
Run Code Online (Sandbox Code Playgroud)

然后创建您的计算字段:

  MyQueryMyField := TStringField.Create(MyQuery);
  with MyQueryMyField do
  begin
    Name := 'MyQueryMyField';
    FieldKind := fkCalculated;
    FieldName := 'MyField';
    Size := 10;
    DataSet := MyQuery;
  end;
Run Code Online (Sandbox Code Playgroud)


r_j*_*r_j 4

Delphi 现在可以选择组合自动生成字段和计算字段:Data.DB.TFieldOptions.AutoCreateMode TFieldsAutoCreationMode类型的枚举。这样您就可以在运行时添加计算字段。弗朗索瓦在他的回答中写道如何在运行时添加字段。

TFieldsAutoCreationMode 的不同模式:

  • ac独家

    当根本没有持久字段时,就会创建自动字段。这是默认模式。

  • acCombine计算

    当数据集没有持久字段或仅存在计算持久字段时,将创建自动字段。这是在设计时创建持久计算字段并让数据集创建自动数据字段的便捷方法。

  • 始终合并

    当没有持久字段时,将创建数据库字段的自动字段。