Desde o PostgreSQL 8.4 (que você parece estar executando), existem valores padrão para parâmetros de função . Se você colocar seu parâmetro por último e fornecer um padrão, poderá simplesmente omiti-lo da chamada:
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$;
Pontos principais:
-
A palavra-chaveDEFAULT
é usado para declarar padrões de parâmetros. Alternativa curta:=
.
-
Eu removi oparam1
redundante do exemplo confuso.
-
Como você retornaSELECT * FROM foobar
, declare o tipo de retorno comoRETURNS SETOF foobar
em vez deRETURNS SETOF record
. O último formulário com registros anônimos é muito complicado, você teria que fornecer uma lista de definição de coluna com cada chamada.
-
Eu uso um array de inteiros (int[]
) como parâmetro de função. Adaptou oIF
expressão e oWHERE
cláusula em conformidade.
-
IF
instruções não estão disponíveis em SQL simples. Tem que serLANGUAGE plpgsql
por isso.
Chamar com ou sem
_ids
:SELECT * FROM foofunc(1, '2012-1-1'::date);
Efetivamente o mesmo:
SELECT * FROM foofunc(1, '2012-1-1'::date, '{}'::int[]);
Você deve certificar-se de que a chamada não seja ambígua. Se você tiver outra função com o mesmo nome e dois parâmetros, o Postgres pode não saber qual escolher. O elenco explícito (como eu demonstro) reduz isso. Caso contrário, literais de string não tipados também funcionam, mas ser explícito nunca é demais.
Chame de dentro de outra função:
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$;