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

Definir um valor de retorno padrão para uma função Postgres


Você precisa alterar o idioma de sql para plpgsql se você quiser usar os recursos procedurais do PL/pgSQL. O corpo da função também muda.

Esteja ciente de que todos os nomes de parâmetros são visíveis no corpo da função , incluindo todos os níveis de instruções SQL. Se você criar um conflito de nomenclatura, talvez seja necessário qualificar os nomes de coluna da tabela como este:table.col , evitar confusão. Como você se refere aos parâmetros da função por referência posicional ($n ) de qualquer forma, acabei de remover os nomes dos parâmetros para fazê-lo funcionar.

Finalmente, THEN estava faltando no IF declaração - a causa imediata da mensagem de erro .

Pode-se usar COALESCE para substituir NULL valores. Mas isso só funciona se houver pelo menos uma linha resultante. COALESCE não pode corrigir "sem linha", só pode substituir NULL real valores.

Existem várias maneiras de cobrir todos os NULL casos. Em funções plpgsql :
CREATE OR REPLACE FUNCTION point_total(integer, date, OUT result bigint)
  RETURNS bigint AS
$func$
BEGIN

SELECT sum(p.points)          -- COALESCE would make sense ...
INTO   result
FROM   picks p
WHERE  p.user_id = $1
AND    p.gametime > $2
AND    p.points IS NOT NULL;  -- ... if NULL values were not ruled out

IF NOT FOUND THEN             -- If no row was found ...
   result := 0;               -- ... set to 0 explicitly
END IF;

END
$func$  LANGUAGE plpgsql;

Ou você pode incluir toda a consulta em um COALESCE expressão em um SELECT externo . "Nenhuma linha" do SELECT interno resulta em um NULL na expressão. Trabalhe como SQL simples ou você pode envolvê-lo em uma função sql :
CREATE OR REPLACE FUNCTION point_total(integer, date)
  RETURNS bigint AS
$func$
SELECT COALESCE(
  (SELECT sum(p.points)
   FROM   picks p
   WHERE  p.user_id = $1
   AND    p.gametime > $2
   -- AND    p.points IS NOT NULL  -- redundant here
  ), 0)
$func$  LANGUAGE sql;

Resposta relacionada:

Com relação a conflitos de nomenclatura


Um problema foi o conflito de nomenclatura mais provável. Houve grandes mudanças na versão 9.0 . Cito as notas de versão :

Versões posteriores refinaram o comportamento. Em pontos óbvios, a alternativa certa é escolhida automaticamente. Reduz o potencial de conflitos, mas ainda existe. O conselho ainda se aplica no Postgres 9.3.