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.