sqlから言語を変更する必要があります plpgsqlへ PL/pgSQLの手続き型機能を使用したい場合。関数本体も変更されます。
すべてのパラメータ名は関数本体に表示されることに注意してください 、すべてのレベルのSQLステートメントを含みます。名前の競合を作成する場合は、次のように列名をテーブル修飾する必要があります:table.col 、混乱を避けるため。関数パラメーターを位置参照で参照するため($n )とにかく、パラメータ名を削除して機能させました。
最後に、THEN IFにありませんでした ステートメント-エラーメッセージの直接の原因 。
COALESCE> NULLの代わりに 値。ただし、これは、結果の行が少なくとも1つある場合にのみ機能します。 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;
関連する回答:
名前の競合について
1つの問題は、最も可能性の高い名前の競合でした。 バージョン9.0に大きな変更がありました 。 リリースノート を引用します :
それ以降のバージョンでは、動作が改善されています。明らかな場所では、適切な選択肢が自動的に選択されます。競合の可能性を減らしますが、それはまだあります。このアドバイスはPostgres9.3でも引き続き適用されます。