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でも引き続き適用されます。