PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL parametrisiertes Order By / Limit in der Tabellenfunktion

An einer plpgsql-Funktion ist nichts auszusetzen für etwas komplexeres. Die einzige Situation, in der die Leistung leiden kann, ist, wenn eine plpgsql-Funktion verschachtelt ist, da der Abfrageplaner den enthaltenen Code im Kontext der äußeren Abfrage nicht weiter optimieren kann, was ihn möglicherweise langsamer macht oder auch nicht.
Weitere Details dazu später Antwort:

  • Unterschied zwischen Sprache sql und Sprache plpgsql in PostgreSQL-Funktionen

Im vorliegenden Fall ist es viel einfacher als viele CASE Klauseln in einer Abfrage:

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;

Aufruf:

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

Notizen

Verwenden Sie RETURN QUERY EXECUTE um die Ergebnisse der Abfrage auf einmal zurückzugeben.

Verwenden Sie quote_ident() für Bezeichner zum Schutz vor SQLi.
Oder format() für etwas komplexeres. Siehe:

  • Tabellenname als PostgreSQL-Funktionsparameter

Übergeben Sie Parameterwerte mit dem USING -Klausel, um erneutes Casting, Zitieren und SQLi zu vermeiden.

Achten Sie darauf, keine Namenskonflikte zwischen Parametern und Spaltennamen zu erzeugen. Ich habe Parameternamen einen Unterstrich vorangestellt (_ ) im Beispiel. Nur meine persönliche Vorliebe.

Ihre zweite Funktion nach der Bearbeitung kann nicht funktionieren, da Sie nur parent zurückgeben während der Rückgabetyp als SETOF stuff deklariert ist . Sie können beliebig deklarieren Rückgabetyp, den Sie mögen, aber die tatsächlichen Rückgabewerte müssen mit der Deklaration übereinstimmen. Vielleicht möchten Sie RETURNS TABLE verwenden dafür.