Nie ma nic złego w funkcji plpgsql za coś bardziej złożonego. Jedyną sytuacją, w której wydajność może ucierpieć, jest zagnieżdżenie funkcji plpgsql, ponieważ planer zapytań nie może dalej optymalizować zawartego kodu w kontekście zapytania zewnętrznego, co może, ale nie musi, spowolnić go.
Więcej szczegółów w dalszej części odpowiedź:
- Różnica między językiem sql a językiem plpgsql w funkcjach PostgreSQL
W tym przypadku jest znacznie prostsze niż wiele CASE
klauzule w zapytaniu:
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;
Zadzwoń:
SELECT * FROM get_stuff('hello', 'col2', 100);
Notatki
Użyj RETURN QUERY EXECUTE
aby zwrócić wyniki zapytania za jednym razem.
Użyj quote_ident()
dla identyfikatorów chroniących przed SQLi.
Lub format()
za coś bardziej złożonego. Zobacz:
- Nazwa tabeli jako parametr funkcji PostgreSQL
Przekaż wartości parametrów za pomocą USING
klauzula, aby ponownie uniknąć rzutowania, cytowania i SQLi.
Uważaj, aby nie tworzyć konfliktów nazw między parametrami a nazwami kolumn. Poprzedziłem nazwy parametrów podkreśleniem (_
) w przykładzie. Tylko moje osobiste preferencje.
Twoja druga funkcja po edycji nie może działać, ponieważ zwracasz tylko parent
gdy typ zwracany jest zadeklarowany SETOF stuff
. Możesz zadeklarować dowolne typ zwrotu, który lubisz, ale rzeczywiste wartości zwracane muszą być zgodne z deklaracją. Możesz użyć RETURNS TABLE
za to.