Имам sql функция, която прави прост sql select оператор:
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: 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),
)
Редактиране2
Лошо прочетох кода на Dems. Коригирах го на въпрос. Този код работи за мен.
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