sql >> Database >  >> RDS >> PostgreSQL

Meerdere sets of arrays van waarden doorgeven aan een functie

Dat bereik je met een simpele SQL-functie. Belangrijkste kenmerk is de functie 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;

Bel:

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

Of hetzelfde met een array letterlijk - wat handiger is in sommige contexten, vooral met voorbereide verklaringen:

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

De functie altijd verwacht een 2D-array. Zelfs als je een enkel paar doorgeeft, nest het dan:

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

Controle van uw implementatie

  1. Je hebt de functie VOLATILE . gemaakt , maar het kan STABLE . zijn . Per documentatie:

    Vanwege dit snapshotgedrag is een functie die alleen SELECT . bevat commando's kunnen veilig worden gemarkeerd als STABLE .

    Gerelateerd:

    • Een parameter doorgeven aan een datumfunctie
  2. Je gebruikt ook LANGUAGE plpgsql in plaats van sql , wat logisch is als u de functie meerdere keren in dezelfde sessie uitvoert. Maar dan moet je het ook STABLE maken of u verliest dat potentiële prestatievoordeel. Nogmaals de handleiding:

    STABLE en IMMUTABLE functies gebruiken een momentopname die is gemaakt vanaf het begin van de aanroepende query, terwijl VOLATILE-functies een verse momentopname krijgen aan het begin van elke query die ze uitvoeren.

  3. Uw EXPLAIN uitvoer toont een Alleen Index Scan , geen sequentiële scan zoals je vermoedt in je opmerking.

  4. Er is ook een sorteerstap in uw EXPLAIN uitvoer die niet overeenkomt met de code die u laat zien. Weet je zeker dat je de juiste EXPLAIN . hebt gekopieerd uitvoer? Hoe heb je die trouwens gekregen? PL/pgSQL-functies zijn zwarte dozen om EXPLAIN . Heb je auto_explain . gebruikt? ? Details:

    • Postgres-queryplan van een UDF-aanroep geschreven in pgpsql
  5. De queryplanner van Postgres heeft geen idee hoeveel array-elementen de doorgegeven parameter zal hebben, dus het is moeilijk om de query te plannen en kan standaard een sequentiële scan uitvoeren (afhankelijk van meer factoren). U kunt helpen door het verwachte aantal rijen aan te geven. Als u doorgaans niet meer dan 10 items heeft, voegt u ROWS 10 toe toe zoals ik nu hierboven deed. En test opnieuw.



  1. PostgreSQL JDBC Null String genomen als bytea

  2. Hoe MariaDB op CentOS 7 / RHEL 7 te installeren

  3. resultaatset van functie retourneren

  4. Alles selecteren voor/na een bepaald teken in MySQL - SUBSTRING_INDEX()