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

Funções com número variável de parâmetros de entrada


Recursos avançados como VARIADIC ou mesmo tipos de entrada polimórficos e SQL dinâmico são muito poderosos. O último capítulo desta resposta fornece um exemplo avançado:
  • Refatorar uma função PL/pgSQL para retornar a saída de várias consultas SELECT

Mas para um caso simples como o seu, basta usar valores padrão para parâmetros de função. Tudo depende dos requisitos exatos.
Se as colunas em questão estão todas definidas NOT NULL , isso provavelmente seria mais simples e rápido:
CREATE OR REPLACE FUNCTION update_site(_name      text    -- always required
                                     , _city      text    DEFAULT NULL
                                     , _telephone integer DEFAULT NULL)
  RETURNS integer AS
$func$
BEGIN
   IF _city IS NULL AND _telephone IS NULL THEN
      RAISE WARNING 'At least one value to update required!';
      RETURN;  -- nothing to update
   END IF;

   UPDATE "Sites"
   SET    "City"      = COALESCE(_city, "City")
        , "Telephone" = COALESCE(_telephone, "Telephone")
   WHERE  "SiteName"  = _name;
END
$func$  LANGUAGE plpgsql;

Leia sobre os valores padrão no manual!

Para evitar conflitos de nomenclatura entre parâmetros e nomes de colunas, tenho o hábito de prefixar os parâmetros de entrada com _ . Isso é uma questão de gosto e estilo.
  • O primeiro parâmetro name não tem padrão, pois é obrigatório o tempo todo.
  • Outros parâmetros podem ser omitidos.
  • Pelo menos um é obrigatório ou um WARNING é gerado e nada mais acontece.
  • A UPDATE só mudará as colunas para determinados parâmetros.
  • Pode ser facilmente expandido para N parâmetros.

Chamada de função


Desde o Postgres 9.5 :

A maneira mais simples é com notação posicional para parâmetros. Isso só permite omitir o(s) parâmetro(s) mais à direita:
SELECT update_site('foo', 'New York');  -- no telephone

Notação nomeada permite omitir qualquer parâmetro que tem um valor padrão:
SELECT update_site(name => 'foo', _telephone => 123);  -- no city

Ambos podem ser combinados em notação mista :
SELECT update_site('foo', _telephone => 123);  -- still no city

No Postgres 9.4 ou mais antigo, := foi usado para atribuição na chamada:
SELECT update_site(name := 'foo', _telephone := 123);
SELECT update_site('foo', _telephone := 123);

Ainda válido no Postgres 12 para compatibilidade com versões anteriores, mas use a notação moderna.