У меня есть функция sql, которая делает простой оператор select sql:
CREATE OR REPLACE FUNCTION getStuff(param character varying)
RETURNS SETOF stuff AS
$BODY$
select *
from stuff
where col = $1
$BODY$
LANGUAGE sql;
Теперь я вызываю эту функцию следующим образом:
select * from getStuff('hello');
Каковы мои варианты, если мне нужно заказать и ограничить результаты предложениями order by
и limit
?
Я предполагаю такой запрос:
select * from getStuff('hello') order by col2 limit 100;
не будет очень эффективным, потому что все строки из таблицы stuff
будут возвращаться функцией getStuff
и только затем упорядочены и разрезаны по значению.
Но даже если я прав, нет простого способа передать порядок аргументам языковой функции sql. Можно передавать только значения, а не части оператора sql.
Другой вариант - создать функцию в plpgsql
языке, где можно построить запрос и выполнить его через EXECUTE
. Но это тоже не очень хороший подход.
Итак, есть ли другой способ достижения этого? Или какой вариант вы бы выбрали? Заказ/ограничение вне функции или plpgsql?
Я использую postgresql 9.1.
Изменить
Я изменил инструкцию CREATE FUNCTION следующим образом:
CREATE OR REPLACE FUNCTION getStuff(param character varying, orderby character varying)
RETURNS SETOF stuff AS
$BODY$
select t.*
from stuff t
where col = $1
ORDER BY
CASE WHEN $2 = 'parent' THEN t.parent END,
CASE WHEN $2 = 'type' THEN t."type" END,
CASE WHEN $2 = 'title' THEN t.title END
$BODY$
LANGUAGE sql;
Это бросает:
ОШИБКА: Невозможно сопоставить символ типа CASE и целое число ŘÁDKA 13: КОГДА $1 = 'parent' THEN t.parentЗабастовкa >
Таблица stuff
выглядит так:
CREATE TABLE stuff
(
id integer serial,
"type" integer NOT NULL,
parent integer,
title character varying(100) NOT NULL,
description text,
CONSTRAINT "pkId" PRIMARY KEY (id),
)
Edit2
Я плохо прочитал код Dems. Я исправил это на вопрос. Этот код работает для меня.