#숫자 타입

숫자 타입설명
{code:noneborderStyle=solid}NUMBER{code}{code:noneborderStyle=none}38자리 정밀도 숫자 저장, 가변 길이(0 ~ 22 바이트){code}
{code:noneborderStyle=solid}BINARY_FLOAT{code}{code:noneborderStyle=none}6자리 단정도 부동소수점 숫자 저장, 고정 길이(5 바이트){code}
{code:noneborderStyle=solid}BINARY_DOUBLE{code}{code:noneborderStyle=none}13자리 배정도 부동소수점 숫자 저장, 고정 길이(9 바이트){code}
Demo#1 (숫자 타입)
{code:sqlborderStyle=solid}
SQL> CREATE TABLE T
( NUM_COL NUMBER,
FLOAT_COL BINARY_FLOAT,
DBL_COL BINARY_DOUBLE
); 2 3 4 5

Table created.

SQL> INSERT INTO T ( NUM_COL, FLOAT_COL, DBL_COL )
VALUES ( 1234567890.0987654321,
1234567890.0987654321,
1234567890.0987654321 ); 2 3 4

1 row created.

SQL> SET NUMFORMAT 9999999999.9999999999
SQL> SELECT * FROM T;

NUM_COL FLOAT_COL DBL_COL






--




--




--
1234567890.0987654321 1234567940.0000000000 1234567890.0987654000
– NUM_COL : 정확한 숫자가 보존
– FLOAT_COL : 7자리 까지 정확
– DBL_COL : 17자리 까지 정확

SQL> DELETE FROM T;

1 row deleted.

SQL> INSERT INTO T ( NUM_COL, FLOAT_COL, DBL_COL )
VALUES ( 9999999999.9999999999,
9999999999.9999999999,
9999999999.9999999999 ); 2 3 4

1 row created.

SQL> SET NUMFORMAT 99999999999.99999999999
SQL> SELECT * FROM T;

NUM_COL FLOAT_COL DBL_COL




















9999999999.99999999990 10000000000.00000000000 10000000000.00000000000
– FLOAT_COL, DBL_COL 은 부정확

SQL> DELETE FROM T;

1 row deleted.

SQL> INSERT INTO T ( NUM_COL) VALUES ( 123 * 1E20 + 123*1E-20 );

1 row created.

– NUM_COL 에 들어온 값이 정밀도를 벗어나서 정확한 값을 표현하지 못함
SQL> SET NUMFORMAT 99999999999999999999999.9999999999999999999999999
SQL> SELECT NUM_COL, 123*1E20, 123*1E-20 FROM T;

NUM_COL













--
123*1E20












--
123*1E-20












--
12300000000000000000000.0000000000000000000000000
12300000000000000000000.0000000000000000000000000
.0000000000000000012300000

SQL> SELECT NUM_COL FROM T WHERE NUM_COL = 123*1E20;

NUM_COL













--
12300000000000000000000.0000000000000000000000000

|

||Demo#2 (NUMBER 타입)||
|{code:sql|borderStyle=solid}
-- NUMBER(PRECISION, SCALE)
-- PRECISION : 전체 자릿수[1 ~ 38] (반올림 후 허용 자릿수, 무결성)
-- SCALE : 소수점 자릿수[-84 ~ 127] (반올림 자리, 값의 표현)

SQL> CREATE TABLE T (NUM_COL NUMBER(5,0));

Table created.

SQL> INSERT INTO T (NUM_COL) VALUES (12345);

1 row created.

SQL> INSERT INTO T (NUM_COL) VALUES (123456);
INSERT INTO T (NUM_COL) VALUES (123456)
                                *
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column
-- 123456 이 NUMBER(5,0) 타입에 위배됨


SQL> CREATE TABLE T (MSG VARCHAR2(10), NUM_COL NUMBER(5,2));

Table created.

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('123.45', 123.45);

1 row created.

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('123.456', 123.456);

1 row created.

SQL>    SELECT * FROM T;

MSG           NUM_COL
---------- ----------
123.45         123.45
123.456        123.46

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('1234', 1234);
INSERT INTO T (MSG, NUM_COL) VALUES ('1234', 1234)
                                             *
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column
-- 1234(1234.00) 가 NUMBER(5,2) 타입에 위배됨 (-999.99 ~ 999.99)


-- NUMBER(5,2) 는 소수점 셋째 자리에서 반올림, NUMBER(5,-2) 는 10 자리에서 반올림
SQL> CREATE TABLE T (MSG VARCHAR2(10), NUM_COL NUMBER(5,-2));

Table created.

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('123.45', 123.45);

1 row created.

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('123.456', 123.456);

1 row created.

SQL> SELECT * FROM T;

MSG           NUM_COL
---------- ----------
123.45            100
123.456           100

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('1234567', 1234567);

1 row created.

SQL> SELECT * FROM T;

MSG           NUM_COL
---------- ----------
123.45            100
123.456           100
1234567       1234600

SQL> INSERT INTO T (MSG, NUM_COL) VALUES ('12345678', 12345678); -- NUMBER(5,-2)는 일곱자리 까지 허용(십의 자리까지는 반올림으로 인해 0)
INSERT INTO T (MSG, NUM_COL) VALUES ('12345678', 12345678)
                                                 *
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column

|

Demo#3 (가변길이 NUMBER 타입)
{code:sqlborderStyle=solid}
SQL> CREATE TABLE T ( X NUMBER, Y NUMBER );

Table created.

SQL> INSERT INTO T ( X )
SELECT TO_NUMBER(RPAD('9', ROWNUM*2, '9'))
FROM ALL_OBJECTS
WHERE ROWNUM <= 11; 2 3 4

11 rows created.

SQL> UPDATE T SET Y = X + 1;

11 rows updated.

SQL> SET NUMFORMAT 9999999999999999999999999
SQL> COLUMN V1 FORMAT 99
SQL> COLUMN V2 FORMAT 99
SQL> SELECT X, Y, VSIZE(X) V1, VSIZE(Y) V2 FROM T ORDER BY X;

X Y V1 V2







--





-- --- ---
99 100 2 2
9999 10000 3 2
999999 1000000 4 2
99999999 100000000 5 2
9999999999 10000000000 6 2
999999999999 1000000000000 7 2
99999999999999 100000000000000 8 2
9999999999999999 10000000000000000 9 2
999999999999999999 1000000000000000000 10 2
99999999999999999999 100000000000000000000 11 2
9999999999999999999999 10000000000000000000000 12 2

11 rows selected.

-- 두개의 유효숫자가 1바이트를 차지한다, Y 컬럼의 유효숫자는 1 한개이며 유효숫자가 아닌 0의 갯수만 저장하면 됨

|

||Demo#4 (부동소수점 숫자 타입)||
|{code:sql|borderStyle=solid}
-- IEEE 표준 부동소수점 숫자 타입, 근삿값으로 사용됨
SQL> SELECT TO_CHAR( 0.3F + 0.1F, '0.99999999999999' ) FROM DUAL;

TO_CHAR(0.3F+0.1F
-----------------
 0.40000000600000
           ^--> 버그가 아니고, IEEE 부동소수점 숫자의 방식에서 나타나는 현상

|

  • Non-native 숫자 타입
Non-native 숫자 타입설명
{code:noneborderStyle=solid}NUMERIC(P,S){code}{code:noneborderStyle=none}NUMBER(P,S){code}
{code:noneborderStyle=solid}DECIMAL(P,S){code}{code:noneborderStyle=none}NUMBER(P,S){code}
{code:noneborderStyle=solid}INTEGER/INT{code}{code:noneborderStyle=none}NUMBER(38){code}
{code:noneborderStyle=solid}SMALLINT{code}{code:noneborderStyle=none}NUMBER(38){code}
{code:noneborderStyle=solid}FLOAT(P){code}{code:noneborderStyle=none}NUMBER{code}
{code:noneborderStyle=solid}DOUBLE PRECISION{code}{code:noneborderStyle=none}NUMBER{code}
{code:noneborderStyle=solid}REAL{code}{code:noneborderStyle=none}NUMBER{code}
Demo#5 (연산성능)
{code:sqlborderStyle=solid}
SQL> CREATE TABLE T
( NUM_TYPE NUMBER,
FLOAT_TYPE BINARY_FLOAT,
DOUBLE_TYPE BINARY_DOUBLE
); 2 3 4 5

Table created.

SQL> INSERT /*+ APPEND */ INTO T
SELECT ROWNUM, ROWNUM, ROWNUM
FROM ALL_OBJECTS; 2 3

71166 rows created.

SQL> COMMIT;

Commit complete.

SQL> EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE;

PL/SQL procedure successfully completed.

SQL> SELECT SUM(LN(NUM_TYPE)) FROM T;

SUM(LN(NUM_TYPE))













--
723961.8875437750063365534204213

call count cpu elapsed disk query current rows


---
--



--

--

--

--

--
total 8 1.82 1.88 58 481 1 2

SQL> SELECT SUM(LN(FLOAT_TYPE)) FROM T;

SUM(LN(FLOAT_TYPE))













--
723961.8875437704800000000000000

call count cpu elapsed disk query current rows


---
--



--

--

--

--

--
total 4 0.02 0.06 0 240 0 1

SQL> SELECT SUM(LN(DOUBLE_TYPE)) FROM T;

SUM(LN(DOUBLE_TYPE))













--
723961.8875437704800000000000000

call count cpu elapsed disk query current rows


---
--



--

--

--

--

--
total 8 0.04 0.05 0 479 0 2

SQL> SET NUMFORMAT 999999.99999999999999
SQL> SELECT SUM(LN(NUM_TYPE)) FROM T;

SUM(LN(NUM_TYPE))






--
723961.88754377500634

SQL> SELECT SUM(LN(DOUBLE_TYPE)) FROM T;

SUM(LN(DOUBLE_TYPE))






--
723961.88754377048000

SQL> SELECT SUM(LN(CAST( NUM_TYPE AS BINARY_DOUBLE) )) FROM T; -- NUMBER 형을 BINARY_DOUBLE 로 CAST 만 해도 효과 있음

SUM(LN(CAST(NUM_TYPEASBINARY_DOUBLE)))










--
723961.88754377048000

call count cpu elapsed disk query current rows


---
--



--

--

--

--

--
total 4 0.04 0.04 0 240 0 1

|