sql >> Base de Datos >  >> RDS >> PostgreSQL

Cómo devolver un valor de una función si no se encuentra ningún valor

Explicación

La raíz del problema es la definición confusa de "nada".

NULL no es nada , simplemente se desconoce qué es exactamente. "Nada" en términos de SQL sería ninguna fila :no se devuelve nada en absoluto. Eso suele suceder cuando no se encuentra ninguna fila. Pero al usar funciones agregadas , eso no puede suceder porque, por documentación:

avg() devuelve NULL cuando no se encuentran filas (entonces no "nada"). Obtienes una fila con un NULL valor como resultado, que sobrescribe su valor inicial en el código que demuestra.

Solución

Envuelva el resultado en COALESCE . Demostración de una función SQL mucho más simple:

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.

Lo mismo se puede usar en una función plpgsql. Esta función puede ser STABLE , podría ayudar con el rendimiento en el contexto de consultas más grandes.

Otros casos

Si realmente puedes obtener sin fila de una consulta, un simple COALESCE fallaría , porque nunca se ejecuta.

Por un valor único resultado, puede envolver toda la consulta como:

SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result

PL/pgSQL tiene la capacidad de verificar antes de regresar de la función. Esto funciona para varias filas con una o más columnas , también. Hay un ejemplo en el manual demostrando el 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 devolver siempre exactamente una fila , también puede usar SQL puro :

SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;

Si el primero SELECT no devuelve ninguna fila, el segundo SELECT devuelve una fila con valores predeterminados.