概要
Googleで検索してもなかなか出てこない「JIS丸め」Oracleファンクションを自作してみた。
ソース
create or replace function JIS_ROUND( v_value NUMBER, v_N NUMBER ) -- -- JIS_ROUND -- -- IN v_value 対象の数 -- v_N 丸める小数点の桁 -- OUT 丸めた数 -- RETURN NUMBER IS a NUMBER := NULL; b NUMBER := NULL; ret NUMBER := NULL; BEGIN -- 丸める桁(v_N)の1つ小さいの桁の数を求める a := trunc( mod( v_value * power( 10, v_N + 1 ), 10 ) ); -- 求めた v_N -1 が桁が5以外なら、ROUND -- 5なら、偶数丸め IF a != 5 THEN ret := ROUND( v_value, v_N ); ELSE -- 丸める桁 b := trunc( mod( v_value * POWER(10, v_N ), 2 ) ); IF b = 0 THEN ret := TRUNC( v_value, v_N ); ELSE ret := ROUND( v_value, v_N ); END IF; END IF; RETURN ret; END JIS_ROUND;
テスト
テストコードを以下に記載する。
DECLARE v_val NUMBER := NULL; v_N NUMBER := NULL; v_ret NUMBER := NULL; v_expand NUMBER := NULL; BEGIN -- -- 実行後、すべて [TEST OK] と表示されればよい。 -- -- 整数部分の丸めテスト v_val := 1234.56; v_N := 0; v_expand := 1234; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); DBMS_OUTPUT.PUT_LINE('v_expand:' || v_expand); DBMS_OUTPUT.PUT_LINE('v_ret:' || v_ret); END IF; v_val := 1235.56; v_N := 0; v_expand := 1236; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); DBMS_OUTPUT.PUT_LINE('v_expand:' || v_expand); DBMS_OUTPUT.PUT_LINE('v_ret:' || v_ret); END IF; v_val := 1235.46; v_N := 0; v_expand := 1235; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); DBMS_OUTPUT.PUT_LINE('v_expand:' || v_expand); DBMS_OUTPUT.PUT_LINE('v_ret:' || v_ret); END IF; v_val := 1235.66; v_N := 0; v_expand := 1236; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); DBMS_OUTPUT.PUT_LINE('v_expand:' || v_expand); DBMS_OUTPUT.PUT_LINE('v_ret:' || v_ret); END IF; -- -- 小数点第1位のテスト -- v_val := 1234.56; v_N := 1; v_expand := 1234.6; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; v_val := 1234.55; v_N := 1; v_expand := 1234.6; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; v_val := 1234.54; v_N := 1; v_expand := 1234.5; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; v_val := 1234.45; v_N := 1; v_expand := 1234.4; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); DBMS_OUTPUT.PUT_LINE('v_expand:' || v_expand); DBMS_OUTPUT.PUT_LINE('v_ret:' || v_ret); END IF; v_val := 1234.44; v_N := 1; v_expand := 1234.4; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; v_val := 1234.46; v_N := 1; v_expand := 1234.5; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; -- -- 整数部分 -- v_val := 1234.56; v_N := -1; v_expand := 1230; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; v_val := 1235.56; v_N := -1; v_expand := 1240; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; v_val := 1236.56; v_N := -1; v_expand := 1240; select JIS_ROUND(v_val, v_N) into v_ret from dual; IF v_expand = v_ret THEN DBMS_OUTPUT.PUT_LINE('TEST OK'); ELSE DBMS_OUTPUT.PUT_LINE('TEST NG'); END IF; END;