delphidatasetfibplus

How to add all fields without opening dataset?


I'm using TFIBDataSet (Firebird dataset component) and I'm trying to automatically create all fields at runtime, without loading any record into the dataset.

Here is the code of my test:

uses
  FIBDatabase, FIBDataSet, Dialogs;

...

var
  Db : TFIBDataBase;
  Tr : TFIBTransaction;
  Dst : TFIBDataSet;
begin
  //connection
  Db := TFIBDatabase.Create(Self);
  Db.ConnectParams.UserName := 'SYSDBA';
  Db.ConnectParams.Password := 'masterkey';
  Db.DatabaseName := 'localhost:mydatabase.fdb';
  Db.SQLDialect := 3;
  Db.Connected := True;

  //transaction
  Tr := TFIBTransaction.Create(Self);
  Tr.DefaultDatabase := Db;
  Tr.Active := True;

  //dataset
  Dst := TFIBDataSet.Create(Self);
  Dst.Database := Db;
  Dst.Transaction := Tr;
  Dst.SelectSQL.Text := 'SELECT * FROM rdb$database';

  //...

  ShowMessage(IntToStr(Dst.FieldCount));
end;

The previous code produces '0' as output..

I've tried using Dst.Open() and it produces '5', but it also executes the SQL query.


Solution

  • I did it by calling FieldDefs.Update and creating the fields from the FieldDefs list.

    uses
      FIBDatabase, FIBDataSet, Dialogs;
    
    ...
    
    var
      Db : TFIBDataBase;
      Tr : TFIBTransaction;
      Dst : TFIBDataSet;
      I : integer;
    begin
      //connection
      Db := TFIBDatabase.Create(Self);
      Db.ConnectParams.UserName := 'SYSDBA';
      Db.ConnectParams.Password := 'masterkey';
      Db.DatabaseName := 'localhost:mydatabase.fdb';
      Db.SQLDialect := 3;
      Db.Connected := True;
    
      //transaction
      Tr := TFIBTransaction.Create(Self);
      Tr.DefaultDatabase := Db;
      Tr.Active := True;
    
      //dataset
      Dst := TFIBDataSet.Create(Self);
      Dst.Database := Db;
      Dst.Transaction := Tr;
      Dst.SelectSQL.Text := 'SELECT * FROM rdb$database';
    
      //create fields
      Dst.FieldDefs.Update();
      for I := 0 to Dst.FieldDefs.Count - 1 do
        Dst.FieldDefs[I].CreateField(Dst);
    
      ShowMessage(IntToStr(Dst.FieldCount));
    end;