Du måste ändra språket från sql
till plpgsql
om du vill använda de processuella funktionerna i PL/pgSQL. Funktionskroppen ändras också.
Tänk på att alla parameternamn är synliga i funktionskroppen , inklusive alla nivåer av SQL-satser. Om du skapar en namnkonflikt kan du behöva tabellkvalificera kolumnnamn så här:table.col
, för att undvika förvirring. Eftersom du refererar till funktionsparametrar med positionsreferens ($n
) hur som helst, jag tog precis bort parameternamn för att få det att fungera.
Slutligen, THEN
saknades i IF
uttalande - den omedelbara orsaken till felmeddelandet .
Man skulle kunna använda COALESCE för att ersätta NULL
värden. Men det fungerar bara om det finns minst en resulterande rad. COALESCE
kan inte fixa "ingen rad" det kan bara ersätta faktiska NULL
värden.
Det finns flera sätt att täcka alla NULL
fall. 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 så kan du bifoga hela frågan i en COALESCE
uttryck i en yttre SELECT
. "Ingen rad" från den inre SELECT
resulterar i en NULL
i uttrycket. Arbeta som vanlig SQL, eller så kan du slå in den 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;
Relaterat svar:
Angående namnkonflikter
Ett problem var namnkonflikten mest troligt. Det har skett stora förändringar i version 9.0 . Jag citerar release notes :
Senare versioner har förfinat beteendet. På uppenbara ställen väljs det rätta alternativet automatiskt. Minskar risken för konflikter, men den finns kvar. Råden gäller fortfarande i Postgres 9.3.