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.