views:

202

answers:

2

Scenerio:

I want to add a calculated field to given (any) dataset during runtime. I don't know any other way to obtain a dataset structure other than performing DataSet.Open method.

But the Open method causes that atleast one row of a data needs to be transfered from server to client. Then I need to close the DataSet, add field and reopen it. This is an unnecessery overhead in my opinion. Is there a better way of doing this? Please not that I want to be able adding a calcuated field to any dataset and I don't know its structure prior to opening.

In pseudocode it looks like this:

DataSet.Open;
DataSet.Close;
RecreateFieldsStructure;
AddCalculatedField;
DataSet.Open;

Thanks for your time.

+8  A: 

You can use DataSet.FieldDefs.Update method. This will still involve some data transfer but no rows will be fetched. You can call this method in the BeforeOpen event of the TDataSet and also add the calculated fields there.

Here's a short example that works for me:

procedure TDataModule.cdsExampleBeforeOpen(DataSet: TDataSet);
var I: Integer;
    TmpField: TDateTimeField;
begin
  // Get field definitions from the server
  DataSet.FieldDefs.Update;

  // Add calculated field
  TmpField := TDateTimeField.Create(DataSet);
  with TmpField do
  begin
    Name := 'Date';
    FieldName := 'Date';
    DisplayLabel := 'Date';
    DisplayFormat := 'ddd ddddd';
    Calculated := True;
  end;
  TmpField.DataSet := DataSet;

  // Create fields from field definitions
  for I := 0 to DataSet.FieldDefs.Count - 1 do
    DataSet.FieldDefs[I].CreateField(DataSet);
end;
Tihauan
+1. Good to know.
Lieven
Thanks, exactly what I wanted. +1
Wodzu
+3  A: 

If I understand your question well; you want to see/know the tables structure before calling the ADOQuery (open) method. if that what you want you can use the ADOConnection methods like (GetFieldNames) and here an example of how to get the field names of the Table (EMP):

procedure TForm2.Button1Click(Sender: TObject);
var
  lstFields: TStringList;
begin
  lstFields := TStringList.Create;
  try
    ADOConnection1.GetFieldNames('EMP', lstFields);
  finally
    lstFields.Free;
  end;
end;

then all fields names are now on (lstFields). I hope this will help.

Regards.

Issam Ali
Thanks Issam, unfortunately this method only gives me field names which are not sufficient to recreate structure of the dataset. I need also a type of particular field. Anyway I am giving +1 cause it is usefull method.
Wodzu