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.