Jak wywołać funkcję bazodanową z parametrem typu array

0

Witajcie,

Wielokrotnie używałem parametrów tablicowych w postgresie ale pierwszy raz przyszło mi przekazać je przez FireDAC w delphi.

Przykład funkcji w postgresql 9.6:

CREATE OR REPLACE FUNCTION test.farrtest (
  aid integer,
  aarrtest integer []
)
RETURNS void AS
$body$
declare
  vEnums integer;
begin
    foreach vEnums in ARRAY aarrtest loop
  		insert into test.ttest(id) values (vEnums);
    end loop;  
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
PARALLEL UNSAFE
COST 100;

delphi:

ADS.Params[0].DataType := vrecord.id.DataType;
ADS.Params[0].Value :=  vrecord.id.value;

ADS.Params[1].DataType := ?;
for i := 0 to sl.count - 1 do
  ADS.Params[1].Values[i].Value := i;

Próbowałem również z arraytype, arraysize i nic ... ktoś wie jak to poprawnie ustawić?

1

może coś w tym stylu:

sl.Delimiter := ',';
ADS.Params[1].Value := '{' + sl.DelimitedText + '}';

przy założeniu, że sl to TStringList z wartościami tablicy
edit: lub jeżeli w delphi masz również tablicę intów to np.:

function IntArrayToParam(arr: array of Integer): String;
var
  i: Integer;
begin
  Result := '';
  for i := Low(arr) to High(arr) do
    if i < High(arr) then
      Result := Result + IntToStr(arr[i]) + ','
    else
      Result := Result + IntToStr(arr[i]);
  Result := '{' + Result + '}';
end;           

...
ADS.Params[1].Value := IntArrayToParam(tablica);
0

Tak też już próbowałem:

('[FireDAC][Stan]-19. Data type conversion is not supported', 0, nil, nil, False)
    ADS.Params[0].DataType := ftInteger;
    ADS.Params[0].Value := 1;
    ADS.Params[1].DataType := ftArray;
    ADS.Params[1].Value := '{1,2,3}';
    ADS.Open;

edit:
W przypadku:

    ADS.Params[0].DataType := ftInteger;
    ADS.Params[0].Value := 1;
    ADS.Params[1].DataType := ftUnknown;
    ADS.Params[1].Value := '{1,2,3}';
    ADS.Open;
('[FireDAC][Phys][PG][libpq] BŁĄD: funkcja test.farrtest(integer, character varying) nie istnieje.'#$D#$A'Brak funkcji pasującej do podanej nazwy i typów argumentów. Być może należy dodać jawne rzutowanie typów.', 0, nil, nil, False)

Problem w tym, że firedac nie widzi tego parametru int [] ... a przynajmniej ja nie umiem tych komponentów wysterować aby je widział poprawnie i konwertuje na varchar ... a tu z kolei baza rzuca błąd, że nie ma takiej funkcji

0

a jeżeli nie ustawisz typu danych dla parametru to też nie puszcza?

1

a próbowałeś skorzystać z makra, a nie parametru

ADS.SQL.Test := 'select farrtest (:id, &arr)';
ADS.Params[0].AsInteger := 1;
ADS.Macros[0].AsRaw := '{1,2,3}';
ADS.Open;
4

https://github.com/Embarcadero/RADStudio10.3Demos/tree/master/Object%20Pascal/Database/FireDAC/Samples/DBMS%20Specific/PostgreSQL/Arrays

ADS.Params[0].AsInteger := 1;
ADS.Params[1].ArrayType := atTable;
ADS.Params[1].ArraySize := 3;
ADS.Params[1].AsIntegers[0] := 1;
ADS.Params[1].AsIntegers[1] := 2;
ADS.Params[1].AsIntegers[2] := 3;

1 użytkowników online, w tym zalogowanych: 0, gości: 1