我正在尝试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
。阅读文档:因此,您应该以建议的形式使用该功能:
并确保参数的实际类型完全匹配。如果列
balance
是数字,则第二个参数也必须是numeric
:更新。OP 说:
在这种情况下,您不能使用
anyelement
参数。您需要使用数字参数创建函数:缺点是该函数仅适用于数字和/或整数参数。Postgres 允许重载函数,因此您可以另外为其他类型创建函数,例如: