sql >> Databasteknik >  >> RDS >> PostgreSQL

Skicka flera uppsättningar eller matriser av värden till en funktion

Du kan uppnå det med en enkel SQL-funktion. Nyckelfunktion är 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:

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

Eller samma sak med en array literal - vilket är bekvämare i vissa sammanhang, särskilt med förberedda uttalanden:

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

Funktionen alltid förväntar sig en 2D-array. Även om du passerar ett enstaka par, kapsla det:

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

Revision av din implementering

  1. Du skapade funktionen VOLATILE , men det kan vara STABLE . Per dokumentation:

    På grund av detta ögonblicksbildbeteende, en funktion som endast innehåller SELECT kommandon kan säkert markeras med STABLE .

    Relaterat:

    • Hur man skickar en parameter till en datumfunktion
  2. Du använder också LANGUAGE plpgsql istället för sql , vilket är vettigt om du kör funktionen flera gånger i samma session. Men då måste du också göra den STABLE eller så förlorar du den potentiella prestationsfördelen. Manualen ännu en gång:

    STABLE och IMMUTABLE funktioner använder en ögonblicksbild som upprättats vid starten av den anropande frågan, medan VOLATILE-funktioner får en ny ögonblicksbild i början av varje fråga de kör.

  3. Din EXPLAIN utdata visar en Endast indexsökning , inte en sekventiell genomsökning som du misstänker i din kommentar.

  4. Det finns också ett sorteringssteg i din EXPLAIN utdata som inte matchar koden du visar. Är du säker på att du kopierade rätt EXPLAIN produktion? Hur fick du det förresten? PL/pgSQL-funktioner är svarta rutor för att EXPLAIN . Använde du auto_explain ? Detaljer:

    • Postgres-frågeplan för en UDF-anrop skriven i pgpsql
  5. Postgres-frågeplaneraren har ingen aning om hur många arrayelement den skickade parametern kommer att ha, så det är svårt att planera frågan och den kan som standard använda en sekventiell skanning (beroende på fler faktorer). Du kan hjälpa till genom att deklarera det förväntade antalet rader. Om du vanligtvis inte har fler än 10 artiklar, lägg till ROWS 10 som jag gjorde nu ovan. Och testa igen.



  1. PostgreSQL återkallar behörigheter från pg_catalog-tabeller

  2. Hämta returvärdet från JDBC MSSQL

  3. Bindestreck i kolumnnamn i MySQL DB

  4. Mysql-behörighetsfel med "ladda data"