У меня есть функция 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.
Edit
Я изменил оператор 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: WHEN $ 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),
)
Edit2
Я плохо прочитал код Dems.Я исправил это к вопросу.Этот код работает для меня.