Musisz zmienić język z sql
do plpgsql
jeśli chcesz korzystać z proceduralnych funkcji PL/pgSQL. Zmienia się również treść funkcji.
Pamiętaj, że wszystkie nazwy parametrów są widoczne w treści funkcji , w tym wszystkie poziomy instrukcji SQL. Jeśli tworzysz konflikt nazw, może być konieczne zakwalifikowanie do tabeli nazw kolumn w następujący sposób:table.col
, aby uniknąć nieporozumień. Ponieważ odwołujesz się do parametrów funkcji przez referencję pozycyjną ($n
) w każdym razie, właśnie usunąłem nazwy parametrów, aby to działało.
Wreszcie THEN
brakowało w IF
oświadczenie - bezpośrednia przyczyna komunikatu o błędzie .
Można by użyć COALESCE zastąpić NULL
wartości. Ale to działa tylko wtedy, gdy istnieje co najmniej jeden wynikowy wiersz. COALESCE
nie można naprawić „brak wiersza”, może tylko zastąpić rzeczywisty NULL
wartości.
Istnieje kilka sposobów na pokrycie wszystkich NULL
sprawy. W funkcjach 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;
Możesz też zawrzeć całe zapytanie w COALESCE
wyrażenie w zewnętrznym SELECT
. „Brak wiersza” z wewnętrznego SELECT
wyniki w NULL
w wyrażeniu. Pracuj jak zwykły SQL lub możesz umieścić go w funkcji 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;
Powiązana odpowiedź:
Dotyczy konfliktów nazw
Jednym z problemów był najprawdopodobniej konflikt nazw. Nastąpiły poważne zmiany w wersji 9.0 . Cytuję informacje o wydaniu :
Późniejsze wersje udoskonaliły zachowanie. W oczywistych miejscach odpowiednia alternatywa jest wybierana automatycznie. Zmniejsza potencjał konfliktów, ale nadal istnieje. Porada nadal obowiązuje w Postgres 9.3.