概要
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;