Sie müssen die Sprache von sql
ändern zu plpgsql
wenn Sie die prozeduralen Features von PL/pgSQL nutzen möchten. Der Funktionskörper ändert sich ebenfalls.
Beachten Sie, dass alle Parameternamen im Funktionskörper sichtbar sind , einschließlich aller Ebenen von SQL-Anweisungen. Wenn Sie einen Namenskonflikt erzeugen, müssen Sie möglicherweise Spaltennamen wie folgt tabellenqualifizieren:table.col
, um Verwirrung zu vermeiden. Da Sie auf Funktionsparameter durch Positionsreferenz verweisen ($n
) trotzdem habe ich nur Parameternamen entfernt, damit es funktioniert.
Zum Schluss THEN
fehlte im IF
-Anweisung - die unmittelbare Ursache der Fehlermeldung .
Man könnte COALESCE um NULL
zu ersetzen Werte. Das funktioniert aber nur, wenn es mindestens eine resultierende Zeile gibt. COALESCE
kann "keine Zeile" nicht beheben, es kann nur das tatsächliche NULL
ersetzen Werte.
Es gibt mehrere Möglichkeiten, alle NULL
abzudecken Fälle. In plpgsql-Funktionen :
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;
Oder Sie können die gesamte Abfrage in ein COALESCE
einschließen Ausdruck in einem äußeren SELECT
. "Keine Zeile" aus dem inneren SELECT
ergibt einen NULL
im Ausdruck. Arbeiten Sie als einfaches SQL, oder Sie können es in eine sql-Funktion packen :
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;
Zugehörige Antwort:
In Bezug auf Namenskonflikte
Ein Problem war höchstwahrscheinlich der Namenskonflikt. In Version 9.0 wurden wichtige Änderungen vorgenommen . Ich zitiere die Versionshinweise :
Spätere Versionen haben das Verhalten verfeinert. An offensichtlichen Stellen wird automatisch die richtige Alternative ausgewählt. Reduziert das Konfliktpotenzial, ist aber immer noch da. Der Rat gilt weiterhin in Postgres 9.3.