sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan returneres en værdi fra en funktion, hvis der ikke findes nogen værdi

Forklaring

Roden til problemet er den uklare definition af "ikke noget".

NULL er ikke ingenting , det er bare uvist, hvad det præcist er. "Intet" i form af SQL ville være ingen række :intet returneres overhovedet. Det sker typisk, når der ikke findes nogen række. Men når du bruger samlede funktioner , det kan ikke ske, fordi pr. dokumentation:

avg() returnerer NULL når ingen rækker findes (altså ikke "ingenting"). Du får en række med en NULL værdi som resultat - som overskriver din init-værdi i den kode, du demonstrerer.

Løsning

Pak resultatet ind i COALESCE . Demonstrerer en meget enklere SQL-funktion:

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.

Det samme kan bruges i en plpgsql-funktion. Denne funktion kan være STABLE , kan hjælpe med ydeevne i forbindelse med større forespørgsler.

Andre sager

Hvis du faktisk kaningen række fra en forespørgsel, en simpel COALESCE ville mislykkes , fordi det aldrig bliver udført.

For en enkelt værdi resultat kan du bare pakke hele forespørgslen som:

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

PL/pgSQL har mulighed for at tjekke, før du rent faktisk vender tilbage fra funktionen. Dette virker for flere rækker med en eller flere kolonner , også. Der er et eksempel i manualen demonstrerer brugen af ​​FOUND :

...
RETURN QUERY SELECT foo, bar ...;

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

Relateret:

For altid at returnere præcis én række , kan du også bruge ren SQL :

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

Hvis den første SELECT returnerer ingen række, den anden SELECT returnerer en række med standardindstillinger.



  1. Rails forespørger grænseflade, hvor klausulen er et problem?

  2. PHP MySQLi Forespørgsel mellem to gange fra selve forespørgslen

  3. MySQL BESTIL EFTER FELT med %

  4. Hvordan SIN() virker i MariaDB