Du skal ændre sproget fra sql
til plpgsql
hvis du vil bruge de proceduremæssige funktioner i PL/pgSQL. Funktionens krop ændres også.
Vær opmærksom på, at alle parameternavne er synlige i funktionsteksten , herunder alle niveauer af SQL-sætninger. Hvis du opretter en navnekonflikt, skal du muligvis tabelkvalificere kolonnenavne som dette:table.col
, for at undgå forvirring. Da du henviser til funktionsparametre ved positionsreference ($n
) alligevel har jeg lige fjernet parameternavne for at få det til at virke.
Til sidst THEN
manglede i IF
sætning - den umiddelbare årsag til fejlmeddelelsen .
Man kunne bruge COALESCE for at erstatte NULL
værdier. Men det virker kun, hvis der er mindst én resulterende række. COALESCE
kan ikke rette "ingen række", det kan kun erstatte faktiske NULL
værdier.
Der er flere måder at dække alle NULL
sager. I plpgsql-funktioner :
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;
Eller du kan omslutte hele forespørgslen i en COALESCE
udtryk i en ydre SELECT
. "Ingen række" fra den indre SELECT
resulterer i en NULL
i udtrykket. Arbejd som almindelig SQL, eller du kan indpakke det i en sql-funktion :
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;
Relateret svar:
Vedrørende navnekonflikter
Et problem var den mest sandsynlige navnekonflikt. Der er sket store ændringer i version 9.0 . Jeg citerer udgivelsesbemærkningerne :
Senere versioner har forfinet adfærden. På oplagte steder vælges det rigtige alternativ automatisk. Reducerer potentialet for konflikter, men det er der stadig. Rådene gælder stadig i Postgres 9.3.