2017-11-17 13 views
1

私はそれは、商業丸められた結果を計算する必要があります間違った計算

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)は私に正しい答えを与えますが、1つのパラメータが集計で計算されている場合は正しくありません。 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の助けになりませんでした。

答えて

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) 

第2のケースで引数を解決する必要があるが、システムの機能が最初に選ばれます。

関数sum(integer)は結果としてbigintを返すことに注意してください。

+0

ひどいので、私はそれについて考えなかった。ありがとうございました。 – Bolpat

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

関連する問題