Musíte změnit jazyk z sql
na plpgsql
pokud chcete používat procedurální funkce PL/pgSQL. Tělo funkce se také mění.
Uvědomte si, že všechny názvy parametrů jsou viditelné v těle funkce , včetně všech úrovní SQL příkazů. Pokud vytvoříte konflikt názvů, možná budete muset kvalifikovat názvy sloupců podle tabulky takto:table.col
, vyhnout se zmatku. Protože na parametry funkce odkazujete polohovým odkazem ($n
), stejně jsem jen odstranil názvy parametrů, aby to fungovalo.
Nakonec THEN
v IF
chybělo výpis – okamžitá příčina chybové zprávy .
Dalo by se použít COALESCE nahradit NULL
hodnoty. Ale to funguje pouze v případě, že existuje alespoň jeden výsledný řádek. COALESCE
nelze opravit "žádný řádek", může pouze nahradit skutečný NULL
hodnoty.
Existuje několik způsobů, jak pokrýt všechny NULL
případy. V funkcích 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;
Nebo můžete celý dotaz uzavřít do COALESCE
výraz ve vnějším SELECT
. "Žádný řádek" z vnitřního SELECT
výsledkem je NULL
ve výrazu. Pracujte jako prostý SQL, nebo jej můžete zabalit do funkce 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;
Související odpověď:
Konflikty názvů
Jedním z problémů byl s největší pravděpodobností konflikt názvů. Ve verzi 9.0 došlo k velkým změnám . Cituji poznámky k vydání :
Pozdější verze vylepšily chování. Na zřejmých místech se automaticky vybere správná alternativa. Snižuje potenciál konfliktů, ale stále existuje. Tato rada stále platí v Postgresu 9.3.