Seit PostgreSQL 8.4 (das Sie anscheinend ausführen) gibt es Standardwerte für Funktionsparameter . Wenn Sie Ihren Parameter an letzter Stelle setzen und einen Standard angeben, können Sie ihn einfach aus dem Aufruf weglassen:
CREATE OR REPLACE FUNCTION foofunc(_param1 integer
, _param2 date
, _ids int[] DEFAULT '{}')
RETURNS SETOF foobar -- declare return type!
LANGUAGE plpgsql AS
$func$
BEGIN -- required for plpgsql
IF _ids <> '{}'::int[] THEN -- exclude empty array and NULL
RETURN QUERY
SELECT *
FROM foobar
WHERE f1 = _param1
AND f2 = _param2
AND id = ANY(_ids); -- "IN" is not proper syntax for arrays
ELSE
RETURN QUERY
SELECT *
FROM foobar
WHERE f1 = _param1
AND f2 = _param2;
END IF;
END -- required for plpgsql
$func$;
Wichtige Punkte:
-
Das Schlüsselwort
DEFAULT
wird verwendet, um Parametervorgaben zu deklarieren. Kurze Alternative:=
. -
Ich habe den überflüssigen
param1
entfernt aus dem chaotischen Beispiel. -
Da Sie
SELECT * FROM foobar
zurückgeben , deklarieren Sie den Rückgabetyp alsRETURNS SETOF foobar
anstelle vonRETURNS SETOF record
. Letztere Form mit anonymen Datensätzen ist sehr unhandlich, man müsste bei jedem Aufruf eine Spaltendefinitionsliste angeben. -
Ich verwende ein Integer-Array (
int[]
) als Funktionsparameter.IF
angepasst Ausdruck und dasWHERE
Klausel entsprechend. -
IF
Anweisungen sind in einfachem SQL nicht verfügbar. MussLANGUAGE plpgsql
sein dafür.
Aufruf mit oder ohne _ids
:
SELECT * FROM foofunc(1, '2012-1-1'::date);
Im Grunde dasselbe:
SELECT * FROM foofunc(1, '2012-1-1'::date, '{}'::int[]);
Sie müssen sicherstellen, dass der Aufruf eindeutig ist. Wenn Sie eine andere Funktion mit demselben Namen und zwei Parametern haben, weiß Postgres möglicherweise nicht, welche Sie auswählen sollen. Explizites Casting (wie ich demonstriere) grenzt es ein. Ansonsten funktionieren auch untypisierte String-Literale, aber es schadet nie, explizit zu sein.
Aufruf aus einer anderen Funktion heraus:
CREATE FUNCTION foofuncwrapper(_param1 integer, _param2 date)
RETURNS SETOF foobar
LANGUAGE plgpsql AS
$func$
DECLARE
_ids int[] := '{1,2,3}';
BEGIN
-- whatever
RETURN QUERY
SELECT * FROM foofunc(_param1, _param2, _ids);
END
$func$;