Postgresql
NVL 的 Postgres 函式
我正在嘗試
NVL
在 postgres 中使用。create or replace function nvl (anyelement, anyelement) returns anyelement language sql as $$ select coalesce(cast( $1 as decimal), cast( $2 as decimal)) $$;
但是,對於以下範例,這對我來說失敗了:
testdb=> select nvl(1,2); ERROR: return type mismatch in function declared to return integer DETAIL: Actual return type is numeric. CONTEXT: SQL function "nvl" during inlining testdb=> SELECT nvl( sum(balance), 0 ) as b FROM db.bank WHERE user = 123; ERROR: function nvl(numeric, integer) does not exist LINE 1: SELECT nvl( sum(balance), 0 ) as b FROM db.bank... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
當我將其更改為:
create or replace function nvl (anyelement, anyelement) returns anyelement language sql as $$ select case when $1 is null then $2 else $1 END $$;
第一個例子有效。但我仍然有失敗:
testdb=> SELECT nvl( sum(balance), 0 ) as b FROM db.bank WHERE user = 123; ERROR: function nvl(numeric, integer) does not exist LINE 1: SELECT nvl( sum(balance), 0 ) as b FROM db.bank...
希望得到一些幫助來解決這個問題。
錯誤是由於對類型使用的誤解造成的
anyelement
。閱讀文件:聲明為 anyelement 的每個位置(參數或返回值)都允許具有任何特定的實際數據類型,但在任何給定的呼叫中,它們都必須是相同的實際類型。
因此,您應該以建議的形式使用該功能:
create or replace function nvl (anyelement, anyelement) returns anyelement language sql as $$ select coalesce($1, $2) $$;
並確保參數的實際類型完全匹配。如果列
balance
是數字,則第二個參數也必須是numeric
:select nvl(sum(balance), 0.0) -- or select nvl(sum(balance), 0::numeric)
更新。OP 說:
我無法更改 SQL。只調整功能。
在這種情況下,您不能使用
anyelement
參數。您需要使用數字參數創建函式:drop function if exists nvl (anyelement, anyelement); create or replace function nvl (numeric, numeric) returns numeric language sql as $$ select coalesce($1, $2) $$;
缺點是該函式僅適用於數字和/或整數參數。Postgres 允許重載函式,因此您可以另外為其他類型創建函式,例如:
create or replace function nvl (text, text) returns text language sql as $$ select coalesce($1, $2) $$;