2018년 12월 31일에 작성한 "단위 변환 함수" 글을 보완한 글입니다.
크기가 큰 숫자 값을 SI 단위로 표시하면 데이터의 가독성을 높일 수 있습니다.
아래 fnc_fmt_num 함수는 숫자 값을 SI 단위로 변환한 문자 값을 반환합니다.
-- 1
CREATE OR REPLACE FUNCTION fnc_fmt_num (
i_val IN NUMBER
, i_div IN NUMBER DEFAULT 1024
)
RETURN VARCHAR2
IS
v_val NUMBER := i_val;
v_idx NUMBER := 1;
v_unit VARCHAR2(8) := CASE WHEN i_div = 1024 THEN ' kmgtpez' ELSE ' KMGTPEZ' END;
BEGIN
IF i_val IS NULL THEN
RETURN NULL;
ELSE
LOOP
EXIT WHEN v_val < i_div;
v_val := v_val / i_div;
v_idx := v_idx + 1;
END LOOP;
RETURN SUBSTR (TO_CHAR (v_val, '9,990.00'), 2) || TRANSLATE (v_idx, '123456789', v_unit);
END IF;
END;
/
아래는 fnc_fmt_num 함수를 사용한 결과입니다.
-- 2
SELECT c1
, fnc_fmt_num (c1) AS c1_fmt
, c2
, fnc_fmt_num (c2, 1000) AS c2_fmt
FROM (SELECT POWER ( 8, ROWNUM) AS c1
, POWER (10, ROWNUM) AS c2
FROM XMLTABLE ('1 to 10'));
C1 C1_FMT C2 C2_FMT
---------- --------- ----------- ---------
8 8.00 10 10.00
64 64.00 100 100.00
512 512.00 1000 1.00K
4096 4.00k 10000 10.00K
32768 32.00k 100000 100.00K
262144 256.00k 1000000 1.00M
2097152 2.00m 10000000 10.00M
16777216 16.00m 100000000 100.00M
134217728 128.00m 1000000000 1.00G
1073741824 1.00g 10000000000 10.00G
10 행이 선택되었습니다.
아래 쿼리의 표현식으로도 숫자 값을 SI 단위로 변환할 수 있습니다.
-- 3
SELECT c1
, CASE
WHEN c1 <= 0
THEN ' 0.00 '
ELSE SUBSTR (TO_CHAR (c1 / POWER (1024, TRUNC (LOG (1024, c1))), '9,990.00'), 2)
|| SUBSTR (' kmgtpez', CEIL (LOG (1024, c1 + 1)), 1)
END AS c1_fmt
, c2
, CASE
WHEN c2 <= 0
THEN ' 0.00 '
ELSE SUBSTR (TO_CHAR (c2 / POWER (1000, TRUNC (LOG (1000, c2))), '9,990.00'), 2)
|| SUBSTR (' KMGTPEZ', CEIL (LOG (1000, c2 + 1)), 1)
END AS c1_fmt
FROM (SELECT POWER ( 8, ROWNUM) AS c1
, POWER (10, ROWNUM) AS c2
FROM XMLTABLE ('1 to 10'));
C1 C1_FMT C2 C2_FMT
---------- --------- ----------- ---------
8 8.00 10 10.00
64 64.00 100 100.00
512 512.00 1000 1.00K
4096 4.00k 10000 10.00K
32768 32.00k 100000 100.00K
262144 256.00k 1000000 1.00M
2097152 2.00m 10000000 10.00M
16777216 16.00m 100000000 100.00M
134217728 128.00m 1000000000 1.00G
1073741824 1.00g 10000000000 10.00G
10 행이 선택되었습니다.
21c에 추가된 SQL Macro를 사용하면 표현식으로 함수를 생성할 수 있습니다.
-- 4
CREATE OR REPLACE FUNCTION fnc_fmt_num2 (
i_val IN NUMBER
, i_div IN NUMBER DEFAULT 1024
)
RETURN VARCHAR2 SQL_MACRO (SCALAR)
IS
BEGIN
RETURN q'[CASE
WHEN i_val <= 0
THEN ' 0.00 '
ELSE SUBSTR (TO_CHAR (i_val / POWER (i_div, TRUNC (LOG (i_div, i_val))), '9,990.00'), 2)
|| SUBSTR (DECODE (i_div, 1024, ' kmgtpez', ' KMGTPEZ'), CEIL (LOG (i_div, i_val + 1)), 1)
END]';
END;
/