У меня есть функция sql, которая выполняет простой оператор выбора 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
Таблица 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),
)
Редактировать2
Я плохо прочитал код Демса. Я исправил это на вопрос. Этот код работает для меня.
EXECUTE
не лучший подход? Не должно иметь большого значения с точки зрения производительности, и это единственное решение, о котором я могу думать. - person a_horse_with_no_name   schedule 15.11.2011select * from getStuff('hello') order by col2 limit 100;
, что мне приятнее писать (с точки зрения всего приложения, которое я создаю) - person JoshuaBoshi   schedule 15.11.2011EXECUTE
будет немного медленнее (из-за дополнительного синтаксического анализа), но я сомневаюсь, что вы сможете измерить разницу. - person a_horse_with_no_name   schedule 15.11.2011EXECUTE
, чемORDER BY CASE
? - person JoshuaBoshi   schedule 15.11.2011