Няма нищо лошо в функцията plpgsql за всичко малко по-сложно. Единствената ситуация, при която производителността може да пострада, е, когато функция plpgsql е вложена, тъй като планирането на заявки не може допълнително да оптимизира съдържащия се код в контекста на външната заявка, което може или не може да го направи по-бавно.
Повече подробности в това по-късно отговор:
- Разлика между език sql и език plpgsql във функциите на PostgreSQL
В случая е много по-просто от многото CASE
клаузи в заявка:
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;
Обадете се:
SELECT * FROM get_stuff('hello', 'col2', 100);
Бележки
Използвайте RETURN QUERY EXECUTE
за да върнете резултатите от заявката наведнъж.
Използвайте quote_ident()
за идентификатори за защита срещу SQLi.
Или format()
за всичко по-сложно. Вижте:
- Име на таблица като параметър на функцията на PostgreSQL
Предайте стойностите на параметрите с USING
клауза за избягване на прехвърляне, цитиране и SQLi отново.
Внимавайте да не създавате конфликти в имената между параметри и имена на колони. Пред имената на параметрите поставих долна черта (_
) в примера. Просто мое лично предпочитание.
Втората ви функция след редакцията не може да работи, защото връщате само parent
докато типът на връщането е деклариран SETOF stuff
. Можете да декларирате всеки тип на връщане, който харесвате, но действителните върнати стойности трябва да съответстват на декларацията. Може да искате да използвате RETURNS TABLE
за това.