在ORACLE數據庫中,NUMBER(P,S)是最多見的數字類型,能夠存放數據範圍爲10^-130~10^126(不包含此值),須要1~22字節(BYTE)不等的存儲空間。P 是Precison的英文縮寫,即精度縮寫,表示有效數字的位數,最多不能超過38個有效數字。S是Scale的英文縮寫,表示從小數點到最低有效數字的位數,它爲負數時,表示從最大有效數字到小數點的位數。有時候,咱們在建立表的時候,NUMBER每每沒有指定P,S的值,那麼默認狀況下,NUMBER的P、S的值分別是多少呢?相信這個問題能問倒一大片DBA。 在以前,我遇到了一個問題,總結整理在「ORACLE NUMBER類型Scale爲0引起的問題」這篇博客當中,當時武斷的判斷「若是不指定p和s,NUMBER類型,它的默認精度值爲38, 默認的scale值爲0」,由於當時參考了官方文檔https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1832html
固然文檔沒有錯誤,文檔應該是指在定義字段數據類型爲NUMBER時,指定了NUMBER類型的P值,可是沒有指定S的值,那麼Scale默認就是0,以下測試所示,當時應該是我本身沒有徹底理解文檔意思,固然文檔也有誤導的嫌疑。git
SQL> drop table test;
Table dropped.
SQL> create table test(id number(38));
Table created.
SQL> insert into test
2 select 123 from dual union all
3 select 123.123 from dual;
2 rows created.
SQL> commit;
Commit complete.
SQL> select * from test;
ID
----------
123
123
SQL>
當在指定字段類型爲NUMBER時,若是P和S都不指定,那麼P和S又是什麼值呢?今天特地實驗驗證了一下,具體實驗過程以下:數據庫
SQL> drop table test;
Table dropped.
SQL> create table test(id number, id1 number(38,4));
Table created.
SQL> insert into test
2 select 12, 12 from dual union all
3 select 12.123456789, 12.123456789 from dual;
2 rows created.
SQL> commit;
Commit complete.
SQL> col id for 999999999999.999999999999999999999999999999999999;
SQL> col id1 for 99999999999.9999999999999999999999999999999999999;
SQL> select * from test;
ID ID1
-------------------------------------------------- --------------------------------------------------
12.000000000000000000000000000000000000 12.0000000000000000000000000000000000000
12.123456789000000000000000000000000000 12.1235000000000000000000000000000000000
SQL>
如上所示,當我插入上面兩條記錄後,發現若是不指定p和s,NUMBER類型,此時的Scale至少是9,咱們繼續測試,插入下面數據oracle
SQL> insert into test
2 select 12.123456789123456789123456789123456,
3 12.123456789123456789123456789123456
4 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
ID ID1
-------------------------------------------------- --------------------------------------------------
12.000000000000000000000000000000000000 12.0000000000000000000000000000000000000
12.123456789000000000000000000000000000 12.1235000000000000000000000000000000000
12.123456789123456789123456789123456000 12.1235000000000000000000000000000000000
以下所示,此時能夠看到Scale的值33了,那麼Scale的值是否能夠繼續變大呢?app
SQL> insert into test
2 select 12.123456789123456789123456789123456789123,
3 12.123456789123456789123456789123456789123
4 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
ID ID1
-------------------------------------------------- --------------------------------------------------
12.000000000000000000000000000000000000 12.0000000000000000000000000000000000000
12.123456789000000000000000000000000000 12.1235000000000000000000000000000000000
12.123456789123456789123456789123456000 12.1235000000000000000000000000000000000
12.123456789123456789123456789123456789 12.1235000000000000000000000000000000000
以下截圖所示,插入的記錄爲12.123456789123456789123456789123456789123,可是顯示的值爲12.123456789123456789123456789123456789,總共爲38位,因爲格式化列的緣故,可能致使部分小數位沒有顯示,測試
咱們繼續測試,調整格式化列,咱們發現值變爲了12.12345678912345678912345678912345678912,總共40位了,Scale的值爲38了。這個是爲何呢?不是數字精度爲38,意味着最可能是38位嗎?ui
SQL> col id for 999999999999.99999999999999999999999999999999999999999
SQL> col id1 for 99999999999.999999999999999999999999999999999999999999
SQL> select * from test;
ID ID1
------------------------------------------------------- -------------------------------------------------------
12.00000000000000000000000000000000000000000 12.000000000000000000000000000000000000000000
12.12345678900000000000000000000000000000000 12.123500000000000000000000000000000000000000
12.12345678912345678912345678912345600000000 12.123500000000000000000000000000000000000000
12.12345678912345678912345678912345678912000 12.123500000000000000000000000000000000000000
繼續其它測試,咱們發現Sacle的值會隨着小數點前面數字的變化而變化,以下所示:spa
SQL> insert into test
2 select 123456789.123456789123456789123456789123456,
3 123456789.123456789123456789123456789123456
4 from dual;
1 row created.
SQL> commit;
Commit complete
SQL> insert into test
2 select 123456789123.123456789123456789123456789123456,
3 123456789123.123456789123456789123456789123456
4 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
ID ID1
------------------------------------------------------- -------------------------------------------------------
12.00000000000000000000000000000000000000000 12.000000000000000000000000000000000000000000
12.12345678900000000000000000000000000000000 12.123500000000000000000000000000000000000000
12.12345678912345678912345678912345600000000 12.123500000000000000000000000000000000000000
12.12345678912345678912345678912345678912000 12.123500000000000000000000000000000000000000
123456789.12345678912345678912345678912300000000000 123456789.123500000000000000000000000000000000000000
123456789123.12345678912345678912345678910000000000000 #######################################################
6 rows selected.
從上面測試能夠看出,Scale的值是變化的,跟數據值有關係,目前看來,小數點前的數字位數和小數點後的數字位數相加爲40(有時候又是39),爲了測試是否這個規律,我特地用下面案例測試一下3d
SQL> create table test2(id number);
Table created.
SQL> insert into test2
2 select 0.123456789123456789123456789123456789123456789 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> col id for 9999999999.9999999999999999999999999999999999999999999999;
SQL> select * from test2;
ID
----------------------------------------------------------
.1234567891234567891234567891234567891235000000
SQL> insert into test2
2 select 123456789.123456789123456789123456789123456789 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test2;
ID
----------------------------------------------------------
.1234567891234567891234567891234567891235000000
123456789.1234567891234567891234567891230000000000000000
SQL> insert into test2
2 select 123456789123.123456789123456789123456789123456789 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test2;
ID
----------------------------------------------------------
.1234567891234567891234567891234567891235000000
123456789.1234567891234567891234567891230000000000000000
##########################################################
SQL> col id for 9999999999999.9999999999999999999999999999999999999999999999;
SQL> select * from test2;
ID
-------------------------------------------------------------
.1234567891234567891234567891234567891235000000
123456789.1234567891234567891234567891230000000000000000
123456789123.1234567891234567891234567891000000000000000000
SQL> insert into test2
2 select 12345678912345.12345678912345678912345678912345 from dual;
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test2;
ID
-------------------------------------------------------------
.1234567891234567891234567891234567891235000000
123456789.1234567891234567891234567891230000000000000000
123456789123.1234567891234567891234567891000000000000000000
#############################################################
SQL> col id for 9999999999999999999.99999999999999999999999999999999999999999999;
SP2-0246: Illegal FORMAT string "9999999999999999999.99999999999999999999999999999999999999999999"
SQL> col id for 9999999999999999999.9999999999999999999999999999999999999999
SQL> select * from test2;
ID
-------------------------------------------------------------
.1234567891234567891234567891234567891235
123456789.1234567891234567891234567891230000000000
123456789123.1234567891234567891234567891000000000000
12345678912345.1234567891234567891234567900000000000000
SQL>
這個問題糾結了好久,不明白爲何是39或40,後面在Oracle Database SQL Reference 10g Release 2終於找到解釋了,以下所示:code
p is the precision, or the total number of significant decimal digits, where the most
significant digit is the left-most nonzero digit, and the least significant digit is the
right-most known digit. Oracle guarantees the portability of numbers with
precision of up to 20 base-100 digits, which is equivalent to 39 or 40 decimal digits
depending on the position of the decimal point.
p是精度,或是有效十進制數的總位數。最大的有效數字是最左邊的非零數字,而最小有效位是最右邊的數字。 Oracle保證數字的可移植性
精度高達20 base-100 digits,至關於39位或40位十進制數字,取決於小數點的位置。