Ich habe eine Sql-Funktion, die eine einfache Sql Select-Anweisung tut:
CREATE OR REPLACE FUNCTION getStuff(param character varying)
RETURNS SETOF stuff AS
$BODY$
select *
from stuff
where col = $1
$BODY$
LANGUAGE sql;
Im Moment rufe ich diese Funktion wie folgt auf:
select * from getStuff('hello');
Welche Möglichkeiten habe ich, wenn ich eine Bestellung aufgeben und die Ergebnisse einschränken muss mit order by
y limit
Klauseln?
Ich denke, eine Anfrage wie diese:
select * from getStuff('hello') order by col2 limit 100;
wäre nicht sehr effizient, da alle Zeilen der Tabelle stuff
wird zurückgegeben von der Funktion getStuff
und erst dann geordnet und in Scheiben geschnitten werden.
Aber selbst wenn ich Recht habe, gibt es keinen einfachen Weg, wie man die Reihenfolge als Argument einer Sql-Sprachfunktion übergeben kann. Es können nur Werte übergeben werden, keine Teile einer SQL-Anweisung.
Eine andere Möglichkeit ist die Erstellung der Funktion in plpgsql
Sprache, in der es möglich ist, die Abfrage zu konstruieren und sie über EXECUTE
. Aber auch das ist kein besonders schöner Ansatz.
Gibt es eine andere Methode, dies zu erreichen? Oder welche Option würden Sie wählen? Anordnung/Begrenzung außerhalb der Funktion oder plpgsql?
Ich verwende Postgresql 9.1.
Editar
Ich habe die CREATE FUNCTION-Anweisung wie folgt geändert:
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;
Das wirft:
ERROR: CASE-Typen Zeichen variierend und Ganzzahl können nicht übereinstimmen RÁDKA 13: WENN $1
En stuff
Tabelle sieht wie folgt aus:
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),
)
Bearbeiten2
Ich habe Dems Code schlecht gelesen. Ich habe ihn auf Frage korrigiert. Dieser Code ist für mich arbeiten.