Трябва да смените езика от sql
към plpgsql
ако искате да използвате процедурните характеристики на PL/pgSQL. Тялото на функцията също се променя.
Имайте предвид, че всички имена на параметри се виждат в тялото на функцията , включително всички нива на SQL изрази. Ако създадете конфликт на именуване, може да се наложи да квалифицирате имена на колони в таблица като това:table.col
, за да избегнете объркване. Тъй като се позовавате на функционални параметри чрез позиционна препратка ($n
) както и да е, току-що премахнах имената на параметрите, за да работи.
И накрая, THEN
липсваше в IF
изявление - непосредствената причина за съобщението за грешка .
Може да се използва COALESCE за заместване на NULL
стойности. Но това работи само ако има поне един резултатен ред. COALESCE
не може да коригира "без ред", може само да замени действителния NULL
стойности.
Има няколко начина за покриване на всички NULL
случаи. В функциите 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;
Или можете да затворите цялата заявка в COALESCE
израз във външен SELECT
. „Няма ред“ от вътрешния SELECT
води до NULL
в израза. Работете като обикновен SQL или можете да го обвиете в 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;
Свързан отговор:
Относно конфликти при именуване
Един от проблемите най-вероятно беше конфликтът с имената. Има големи промени във версия 9.0 . Цитирам бележките по изданието :
По-късните версии са усъвършенствали поведението. На очевидни места правилната алтернатива се избира автоматично. Намалява потенциала за конфликти, но все още е там. Съветът все още е в сила в Postgres 9.3.