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

Como retornar um valor de uma função se nenhum valor for encontrado

Explicação


A raiz do problema é a definição difusa de "nada".

NULL não é nada , é apenas desconhecido o que é exatamente. "Nada" em termos de SQL seria nenhuma linha :nada é retornado. Isso normalmente acontece quando nenhuma linha é encontrada. Mas ao usar funções agregadas , isso não pode acontecer porque, por documentação:

avg() retorna NULL quando nenhuma linha for encontrada (portanto, não "nada"). Você obtém uma linha com um NULL valor como resultado - que substitui seu valor de inicialização no código que você demonstra.

Solução


Envolva o resultado em COALESCE . Demonstrando uma função SQL muito mais simples:
CREATE OR REPLACE FUNCTION get_height_sql(firstn varchar, lastn varchar)
  RETURNS float AS
$func$
   SELECT COALESCE(AVG(((p.h_feet * 12) + p.h_inches) * 2.54)::float, 0)
   FROM   player p
   WHERE  p.firstname = firstn
   AND    p.lastname = lastn
$func$  LANGUAGE sql STABLE;

SQL Fiddle.

O mesmo pode ser usado em uma função plpgsql. Esta função pode ser STABLE , pode ajudar no desempenho no contexto de consultas maiores.

Outros casos


Se você realmente pode obter nenhuma linha de uma consulta, um simples COALESCE faria , porque nunca é executado.

Por um valor único resultado, você pode simplesmente envolver toda a consulta como:
SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result

O PL/pgSQL tem a capacidade de verificar antes de retornar da função. Isso funciona para várias linhas com uma ou mais colunas , também. Há um exemplo em o manual demonstrando o uso de FOUND :
...
RETURN QUERY SELECT foo, bar ...;

IF NOT FOUND THEN
    RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...

Relacionado:

Para sempre retornar exatamente uma linha , você também pode usar SQL puro :
SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;

Se o primeiro SELECT não retorna nenhuma linha, o segundo SELECT retorna uma linha com padrões.