sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL geparametriseerde Order By / Limit in tabelfunctie

Er is niets mis met een plpgsql-functie voor alles wat ingewikkelder is. De enige situatie waarin de prestaties kunnen lijden, is wanneer een plpgsql-functie is genest, omdat de queryplanner de ingesloten code in de context van de buitenste query niet verder kan optimaliseren, waardoor deze al dan niet langzamer wordt.
Hier later meer details over antwoord:

  • Verschil tussen taal sql en taal plpgsql in PostgreSQL-functies

In het onderhavige geval is het veel eenvoudiger dan veel CASE clausules in een zoekopdracht:

CREATE OR REPLACE FUNCTION get_stuff(_param text, _orderby text, _limit int)
  RETURNS SETOF stuff AS
$func$
BEGIN
   RETURN QUERY EXECUTE '
      SELECT *
      FROM   stuff
      WHERE  col = $1
      ORDER  BY ' || quote_ident(_orderby) || ' ASC
      LIMIT  $2'
   USING _param, _limit;
END
$func$  LANGUAGE plpgsql;

Bel:

SELECT * FROM get_stuff('hello', 'col2', 100);

Opmerkingen

Gebruik RETURN QUERY EXECUTE om de resultaten van de zoekopdracht in één keer te retourneren.

Gebruik quote_ident() voor identifiers om te beschermen tegen SQLi.
Of format() voor alles wat ingewikkelder is. Zie:

  • Tabelnaam als een PostgreSQL-functieparameter

Geef parameterwaarden door met de USING clausule om opnieuw casten, citeren en SQLi te voorkomen.

Zorg ervoor dat u geen naamgevingsconflicten creëert tussen parameters en kolomnamen. Ik heb parameternamen voorafgegaan door een onderstrepingsteken (_ ) in het voorbeeld. Gewoon mijn persoonlijke voorkeur.

Je tweede functie na de bewerking kan niet werken, omdat je alleen parent . teruggeeft terwijl het retourtype wordt gedeclareerd SETOF stuff . U kunt elke . declareren retourtype dat u leuk vindt, maar de werkelijke retourwaarden moeten overeenkomen met de aangifte. Misschien wilt u RETURNS TABLE . gebruiken daarvoor.



  1. SQLiteDatabase Cursor alleen leeg op Android 5.0+ apparaten

  2. Linux-bestandssystemen en PostgreSQL-controlepuntbenchmarks

  3. Toon alle query's die naar een Oracle-database komen

  4. Een login.sql-bestand maken voor SQLcl