Sql 如何在Postgres 9.1+函数中使用混合整数和数字参数
我正在寻找一种方法来创建一个icase函数,它可以与任何第二个和第三个参数兼容的数据类型一起工作。 我在Postgres 9.4中尝试过:Sql 如何在Postgres 9.1+函数中使用混合整数和数字参数,sql,postgresql,parameter-passing,plpgsql,iif,Sql,Postgresql,Parameter Passing,Plpgsql,Iif,我正在寻找一种方法来创建一个icase函数,它可以与任何第二个和第三个参数兼容的数据类型一起工作。 我在Postgres 9.4中尝试过: CREATE OR REPLACE FUNCTION public.icase( cond1 boolean, res1 anyelement, conddefault anyelement) RETURNS anyelement AS ' SELECT CASE WHEN $1 THEN $2 ELSE $3 END; '
CREATE OR REPLACE FUNCTION public.icase(
cond1 boolean,
res1 anyelement,
conddefault anyelement)
RETURNS anyelement AS
' SELECT CASE WHEN $1 THEN $2 ELSE $3 END; '
LANGUAGE sql IMMUTABLE;
但是:
导致错误的原因:
如何在9.1+中解决这个问题,使第二个和第三个参数可以是int或numeric
如果第二个和第三个参数都是text、charn、date、numeric或int类型,则可以调用此方法。此时多态类型是严格的-在其他情况下,PostgreSQL尝试将常量强制转换为最常见的类型,但多态类型缺少此步骤-因此在本例中,当您描述问题时,必须显式强制转换,否则不应使用多态类型。方案B是过度的函数重载 然后,您的代码将按预期工作: postgres=> select icase1(true, 1.0, 0); icase1 -------- 1.0 (1 row) postgres=> select icase1(true, 1.0, 1.0); icase1 -------- 1.0 (1 row) postgres=> select icase1(true, 1, 0); icase1 -------- 1 (1 row)
问题是,anyelement每个函数只解析为一种数据类型,而不是每次使用。即使您避免使用任何元素并使用硬编码的数据类型,也无法编写返回数值或整数值的函数。每个函数必须选择一个。我想,如果您将函数调用更改为选择icasetrue,1.0,0.0,它将按预期工作。换句话说,我将以此作为一个提示,开始研究如何预处理您的输入,以将这些内容转换为使用postgres所需的格式。等等,第二个和第三个参数在任何情况下都应该是相同的:int或numeric或date等。?您的标题和示例提示的方向与您的最终陈述不同。。。此外,您是否需要结果具有完全相同的数据类型,或者文本表示法可以完成此任务?第二个和第三个参数可以是:int、numeric、numeric、int、int、int、numeric、date、date、charn、charn、text、text,对于混合的numeric/int参数,结果可以始终是数值的。对于非混合参数,结果应与参数类型相同。对于数字和日期参数,文本结果可能无法返回,因为这在表达式中使用,如果文本在数字表达式中使用,Prosgres可能会产生错误。9.1+@Shawn可能不再支持自动转换。这是从自动转换器调用的,该转换器将VFP表达式转换为postgres。两种不同的语言使用相同的表达式。因此,表达式已经定义,应该避免对其进行更改。
ERROR: function icase(boolean, numeric, integer) does not exist
LINE 9: select icase( true, 1.0, 0 )
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
CREATE OR REPLACE FUNCTION public.icase1(cond1 boolean,
res1 integer, conddefault integer)
RETURNS integer AS $$
SELECT CASE WHEN $1 THEN $2 ELSE $3 END;
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION public.icase1(cond1 boolean,
res1 numeric, conddefault numeric)
RETURNS numeric AS $$
SELECT CASE WHEN $1 THEN $2 ELSE $3 END;
$$ LANGUAGE sql;
postgres=> select icase1(true, 1.0, 0);
icase1
--------
1.0
(1 row)
postgres=> select icase1(true, 1.0, 1.0);
icase1
--------
1.0
(1 row)
postgres=> select icase1(true, 1, 0);
icase1
--------
1
(1 row)