Siden PostgreSQL 8.4 (som du ser ud til at køre), er der standardværdier for funktionsparametre . Hvis du sætter din parameter sidst og angiver en standard, kan du blot udelade den fra opkaldet:
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$;
Vigtigste punkter:
-
Søgeordet
DEFAULT
bruges til at erklære parameterstandarder. Kort alternativ:=
. -
Jeg fjernede den overflødige
param1
fra det rodede eksempel. -
Siden du returnerer
SELECT * FROM foobar
, erklærer returtypen somRETURNS SETOF foobar
i stedet forRETURNS SETOF record
. Sidstnævnte formular med anonyme registreringer er meget uhåndterlig, du skal give en kolonnedefinitionsliste med hvert opkald. -
Jeg bruger en matrix af heltal (
int[]
) som funktionsparameter. TilpassetIF
udtryk ogWHERE
klausul i overensstemmelse hermed. -
IF
sætninger er ikke tilgængelige i almindelig SQL. Skal væreLANGUAGE plpgsql
for det.
Ring med eller uden _ids
:
SELECT * FROM foofunc(1, '2012-1-1'::date);
Faktisk det samme:
SELECT * FROM foofunc(1, '2012-1-1'::date, '{}'::int[]);
Du skal sikre dig, at opkaldet er entydigt. Hvis du har en anden funktion af samme navn og to parametre, ved Postgres måske ikke, hvilken du skal vælge. Eksplicit casting (som jeg demonstrerer) indsnævrer det. Ellers virker utypelige strenge bogstaver også, men at være eksplicit skader aldrig.
Ring fra en anden funktion:
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$;