sql >> Database >  >> RDS >> PostgreSQL

Stel een standaard retourwaarde in voor een Postgres-functie

U moet de taal wijzigen van sql naar plpgsql als u de procedurele kenmerken van PL/pgSQL wilt gebruiken. De functietekst verandert ook.

Houd er rekening mee dat alle parameternamen zichtbaar zijn in de hoofdtekst van de functie , inclusief alle niveaus van SQL-instructies. Als u een naamgevingsconflict creëert, moet u mogelijk kolomnamen als volgt kwalificeren:table.col , om verwarring te voorkomen. Aangezien u naar functieparameters verwijst door middel van positionele referentie ($n ) hoe dan ook, ik heb zojuist parameternamen verwijderd om het te laten werken.

Tot slot, THEN ontbrak in de IF statement - de directe oorzaak van de foutmelding .

Je zou COALESCE ter vervanging van NULL waarden. Maar dat werkt alleen als er ten minste één resulterende rij is. COALESCE kan "geen rij" niet repareren, het kan alleen de werkelijke NULL vervangen waarden.

Er zijn verschillende manieren om alle NULL . te dekken gevallen. In plpgsql-functies :

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;

Of u kunt de hele zoekopdracht insluiten in een COALESCE uitdrukking in een buitenste SELECT . "Geen rij" van de binnenste SELECT resulteert in een NULL in de uitdrukking. Werk als gewone SQL, of je kunt het in een sql-functie plaatsen :

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;

Gerelateerd antwoord:

Over naamgevingsconflicten

Een probleem was waarschijnlijk het naamgevingsconflict. Er zijn grote wijzigingen aangebracht in versie 9.0 . Ik citeer de release-opmerkingen :

Latere versies hebben het gedrag verfijnd. Op voor de hand liggende plekken wordt automatisch het juiste alternatief gekozen. Vermindert de kans op conflicten, maar het is er nog steeds. Het advies is nog steeds van toepassing in Postgres 9.3.




  1. Hoe een lege string voor integer in MySQL toe te staan?

  2. Meerdere velden sorteren in MySQL

  3. Hoe maak je een lijst van alle paren van locatie met hetzelfde gebied uit de tabel in Oracle?

  4. Tenant-ID doorgeven via sql-serververbinding