sql >> Database teknologi >  >> RDS >> PostgreSQL

Send flere sæt eller arrays af værdier til en funktion

Det kan du opnå med en simpel SQL-funktion. Nøglefunktion er funktionen generate_subscripts() :

CREATE OR REPLACE FUNCTION f_attendance(_arr2d int[])
  RETURNS SETOF attendance AS
$func$
   SELECT a.*
   FROM   generate_subscripts($1, 1) i
   JOIN   attendance a ON a.class   = $1[i][1]
                      AND a.section = $1[i][2]
$func$  LANGUAGE ROWS 10 sql STABLE;

Ring til:

SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);

Eller det samme med en matrix literal - hvilket er mere bekvemt i nogle sammenhænge, ​​især med forberedte udsagn:

SELECT * FROM f_attendance('{{1,1},{2,2}}');

Funktionen altid forventer et 2D-array. Selvom du passerer et enkelt par, skal du indlejre det:

SELECT * FROM f_attendance('{{1,1}}');

Revision af din implementering

  1. Du lavede funktionen VOLATILE , men det kan være STABLE . Per dokumentation:

    På grund af denne snapshot-adfærd, en funktion, der kun indeholder SELECT kommandoer kan sikkert markeres med STABLE .

    Relateret:

    • Sådan overføres en parameter til en datofunktion
  2. Du bruger også LANGUAGE plpgsql i stedet for sql , hvilket giver mening, hvis du udfører funktionen flere gange i samme session. Men så skal du også gøre den STABLE eller du mister den potentielle præstationsfordel. Manualen endnu en gang:

    STABLE og IMMUTABLE funktioner bruger et øjebliksbillede etableret ved starten af ​​den kaldende forespørgsel, hvorimod VOLATILE funktioner opnår et nyt øjebliksbillede i starten af ​​hver forespørgsel, de udfører.

  3. Din EXPLAIN output viser en Kun indeksscanning , ikke en sekventiel scanning, som du har mistanke om i din kommentar.

  4. Der er også et sorteringstrin i din EXPLAIN output, der ikke matcher den kode, du viser. Er du sikker på, at du har kopieret den rigtige EXPLAIN produktion? Hvordan fik du det alligevel? PL/pgSQL-funktioner er sorte bokse til EXPLAIN . Brugte du auto_explain ? Detaljer:

    • Postgres-forespørgselsplan for en UDF-invokation skrevet i pgpsql
  5. Postgres-forespørgselsplanlæggeren har ingen idé om, hvor mange array-elementer den beståede parameter vil have, så det er svært at planlægge forespørgslen, og det kan som standard være en sekventiel scanning (afhængigt af flere faktorer). Du kan hjælpe ved at angive det forventede antal rækker. Hvis du typisk ikke har mere end 10 varer, skal du tilføje ROWS 10 som jeg gjorde nu ovenfor. Og test igen.



  1. Konverter SQL Server-forespørgsel til MySQL

  2. Hvordan forespørger man efter null-værdier i json-felttypen postgresql?

  3. Hvordan finder man alle tabeller, der har fremmednøgler, der refererer til bestemt table.column og har værdier for disse fremmednøgler?

  4. Er det muligt at dræbe en enkelt forespørgsel i oracle uden at dræbe sessionen?