PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Argumento opcional na função PL/pgSQL


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-chave DEFAULT é usado para declarar padrões de parâmetros. Alternativa curta:= .

  • Eu removi o param1 redundante do exemplo confuso.

  • Como você retorna SELECT * FROM foobar , declare o tipo de retorno como RETURNS SETOF foobar em vez de RETURNS 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 o IF expressão e o WHERE cláusula em conformidade.

  • IF instruções não estão disponíveis em SQL simples. Tem que ser LANGUAGE 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$;