用户定义的SQL函数错误计算

时间:2017-11-17 23:52:39

标签: sql postgresql user-defined-functions postgresql-9.4

我有一个由

定义的功能
CREATE OR REPLACE FUNCTION public.div(dividend INTEGER, divisor INTEGER)
    RETURNS INTEGER
    LANGUAGE 'sql'
    IMMUTABLE
    LEAKPROOF
    STRICT
    SECURITY DEFINER
    PARALLEL SAFE
    AS $BODY$
        SELECT ($1 + $2/2) / $2;
    $BODY$;

它应该计算商业圆形结果。大多数时候,它完成了这项工作。我不知道为什么,但select div(5, 3)给了我正确的答案,而当一个参数是由汇总计算时,{ select div(sum(val), 3) from (select 1 as val UNION SELECT 4) list足以触发它。 我该如何解决div?我不想投出所有意见。

顺便说一句,使用SELECT (cast($1 as integer) + cast($2 as integer)/2) / cast($2 as integer);作为div的定义并没有帮助。

2 个答案:

答案 0 :(得分:1)

更改功能名称。

函数div(numeric, numeric)是一个内置的Postgres函数,你想要调用函数的含糊不清:

select div(5, 3)           -- calls your function public.div(integer, integer)
select div(5::bigint, 3)   -- calls pg_catalog.div(numeric, numeric)

在第二种情况下,必须解析参数,并选择系统函数。

请注意,函数sum(integer)会产生bigint。

答案 1 :(得分:1)

允许浮点数作为参数,然后在计算时显式转换,否则在传递参数时会有隐含的转换。

CREATE OR REPLACE FUNCTION my_div(dividend FLOAT, divisor FLOAT)
    RETURNS INTEGER
    LANGUAGE 'sql'
    IMMUTABLE
    -- LEAKPROOF -- not allowed at dbfiddle.uk
    STRICT
    SECURITY DEFINER
    PARALLEL SAFE
    AS $BODY$
        SELECT --($1 + $2/2) / $2;
           (cast($1 as integer) + cast($2 as integer)/2) / cast($2 as integer)
    $BODY$;
select my_div(sum(val), 3) 
from (select 1 as val UNION SELECT 4) x
| my_div |
| -----: |
|      2 |

dbfiddle here