5

On pgAdmin with a simple query 'select * from data' I got only one record containing a field type text[] with value '{"1","2","3"}'. The following simplified code gives back only the "1" part of the value:

function GetData: string;
var
  q: TFDQuery;
  s: string;
  i: integer;
  av: array of variant;
  as: array of string;
begin
  result:='';
  q:=TFDQuery.Create(nil);
  try
    q.Connection:=FDConnection;
    q.SQL.Text:='select * from data';
    try
        q.Open;
        while not q.Eof do
        begin
            //s:=q.FieldByName('data_array').AsString;      //s = '1'
            //as:=q.FieldByName('data_array').AsVariant;    //as length = 1; as[0] = '1'        
            av:=q.FieldByName('data_array').AsVariant;
            for i:=0 to Length(av)-1 do s:=s+av[i];         //av length = 1; s = '1'        
            q.Next;
        end;
        result:=q.RecordCount;
    except
        result:=-2;
    end;
    finally
        q.Free;
        sl.Free;
    end;
end;

What is the way to get the whole data?

FGabor
  • 53
  • 1
  • 3
  • Why have you not said which database backend you are using and what column type 'data_array' is in the server table you are querying? Do you not think those might be relevant? – MartynA Apr 10 '17 at 08:09
  • MartynA: it is Postgresql 8.2.7. Field type is text[]. Filedbyname gives back an 'array of variant'. – FGabor Apr 10 '17 at 08:43
  • I've never used these types of fields... but if it's returning an array of variant, maybe you should look into the variant array functions in System.Variants: VarArrayDimCount, VarArrayLowBound, VarArrayHighBound, VarArrayGet, etc... – Frazz Apr 10 '17 at 09:30
  • @Frazz: DimCount = 1, LowBound = 0, HighBound = 0, Get = '1'. – FGabor Apr 10 '17 at 10:33

1 Answers1

4

Although Embarcadero documentation says you should use TArrayField casting (It works for Interbase):

procedure TFrmMain.Button1Click(Sender: TObject);
var
F: TArrayField;
V: Variant;
begin
F := TArrayField(q.FieldByName('data_array'));
V := F.FieldValues[0];
ShowMessage(VarToStr(V));
end;

It seem not to work correctly for PostgreSQL ( at least with C++ builder XE6 i am getting only first array item). Firedac handles PostgreSQL array fields as nested datasets, therefore if above doesn't work for you as well, in C++ you might use PG array as ordinary DataSet, accessing items by moving cursor e.g :

TDataSetField * TT = (TDataSetField*)q->FieldByName("data_array");
TT->NestedDataSet->RecNo=2; // or while(!q->NestedDataSet->eof) etc.
ShowMessage(TT->NestedDataSet->Fields->Fields[0]->AsString);

wchich translated to delphi in your case would look like ( may be misspelled):

...
var
TT: TDataSetField;
...
begin
TT:= TDataSetField(q.FieldByName('data_array'));
    while not TT.NestedDataSet.Eof do
    begin
        s:= s+ TT.NestedDataSet.Fields.Fields[0].AsString; //0 - only single dimension supported
        TT.NestedDataSet.Next;
    end;
end;

Kind regards

Vancalar
  • 963
  • 1
  • 7
  • 15