Depuis PostgreSQL 8.4 (que vous semblez exécuter), il existe des valeurs par défaut pour les paramètres de fonction . Si vous placez votre paramètre en dernier et fournissez une valeur par défaut, vous pouvez simplement l'omettre de l'appel :
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$;
Principaux points :
-
Le mot clé
DEFAULT
est utilisé pour déclarer les paramètres par défaut. Alternative courte :=
. -
J'ai supprimé le
param1
redondant de l'exemple désordonné. -
Depuis que vous retournez
SELECT * FROM foobar
, déclarez le type de retour commeRETURNS SETOF foobar
au lieu deRETURNS SETOF record
. Ce dernier formulaire avec des enregistrements anonymes est très peu maniable, vous devez fournir une liste de définitions de colonnes à chaque appel. -
J'utilise un tableau d'entiers (
int[]
) comme paramètre de fonction. Adapté leIF
expression et leWHERE
clause en conséquence. -
IF
les instructions ne sont pas disponibles en SQL brut. Doit êtreLANGUAGE plpgsql
pour ça.
Appel avec ou sans _ids
:
SELECT * FROM foofunc(1, '2012-1-1'::date);
Effectivement le même :
SELECT * FROM foofunc(1, '2012-1-1'::date, '{}'::int[]);
Vous devez vous assurer que l'appel est sans ambiguïté. Si vous avez une autre fonction du même nom et deux paramètres, Postgres ne saura peut-être pas lequel choisir. Le casting explicite (comme je le démontre) le réduit. Sinon, les littéraux de chaîne non typés fonctionnent également, mais être explicite ne fait jamais de mal.
Appel depuis une autre fonction :
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$;