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.