oracle精度说明符1~38_ORACLE 中NUMBER类型默认的精度和Scale问题

在ORACLE数据库中,NUMBER(P,S)是最常见的数字类型,可以存放数据范围为10^-130~10^126(不包含此值),需要1~22字节(BYTE)不等的存储空间。P是Precison的英文缩写,即精度缩写,表示有效数字的位数,最多不能超过38个有效数字。S是Scale的英文缩写,表示从小数点到最低有效数字的位数,它为负数时,表示从最大有效数字到小数点的位数。有时候,我们在创建表的时候,NUMBER往往没有指定P,S的值,那么默认情况下,NUMBER的P、S的值分别是多少呢?相信这个问题能问倒一大片DBA。 在之前,我遇到了一个问题,总结整理在”这篇博客当中,当时武断的判断“如果不指定p和s,NUMBER类型,它的默认精度值为38,默认的scale值为0”,因为当时参考了官方文档https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1832

当然文档没有错误,文档应该是指在定义字段数据类型为NUMBER时,指定了NUMBER类型的P值,但是没有指定S的值,那么Scale默认就是0,如下测试所示,当时应该是我自己没有完全理解文档意思,当然文档也有误导的嫌疑。

SQL> drop table test;Table dropped.SQL> create table test(id number(38));Table created.SQL> insert into test2  select 123 from dual union all3  select 123.123 from dual;2 rows created.SQL> commit;Commit complete.SQL> select * from test;ID----------123123SQL>

当在指定字段类型为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 test2  select 12, 12 from dual union all3  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.000000000000000000000000000000000000012.123456789000000000000000000000000000           12.1235000000000000000000000000000000000SQL>

如上所示,当我插入上面两条记录后,发现如果不指定p和s,NUMBER类型,此时的Scale至少是9,我们继续测试,插入下面数据

SQL> insert into test2  select 12.123456789123456789123456789123456,3         12.1234567891234567891234567891234564  from dual;1 row created.SQL> commit;Commit complete.SQL> select * from test;ID                                                ID1-------------------------------------------------- --------------------------------------------------12.000000000000000000000000000000000000           12.000000000000000000000000000000000000012.123456789000000000000000000000000000           12.123500000000000000000000000000000000012.123456789123456789123456789123456000           12.1235000000000000000000000000000000000

如下所示,此时可以看到Scale的值33了,那么Scale的值是否可以继续变大呢?

SQL> insert into test2  select 12.123456789123456789123456789123456789123,3         12.1234567891234567891234567891234567891234  from dual;1 row created.SQL> commit;Commit complete.SQL> select * from test;ID                                                ID1-------------------------------------------------- --------------------------------------------------12.000000000000000000000000000000000000           12.000000000000000000000000000000000000012.123456789000000000000000000000000000           12.123500000000000000000000000000000000012.123456789123456789123456789123456000           12.123500000000000000000000000000000000012.123456789123456789123456789123456789           12.1235000000000000000000000000000000000

如下截图所示,插入的记录为12.123456789123456789123456789123456789123,但是显示的值为12.123456789123456789123456789123456789,总共为38位,由于格式化列的缘故,可能导致部分小数位没有显示,

我们继续测试,调整格式化列,我们发现值变为了12.12345678912345678912345678912345678912,总共40位了,Scale的值为38了。这个是为什么呢?不是数字精度为38,意味着最多是38位吗?

SQL> col id  for 999999999999.99999999999999999999999999999999999999999SQL> col id1 for 99999999999.999999999999999999999999999999999999999999SQL> select * from test;ID                                                     ID1------------------------------------------------------- -------------------------------------------------------12.00000000000000000000000000000000000000000           12.00000000000000000000000000000000000000000012.12345678900000000000000000000000000000000           12.12350000000000000000000000000000000000000012.12345678912345678912345678912345600000000           12.12350000000000000000000000000000000000000012.12345678912345678912345678912345678912000           12.123500000000000000000000000000000000000000

继续其它测试,我们发现Sacle的值会随着小数点前面数字的变化而变化,如下所示:

SQL> insert into test2  select 123456789.123456789123456789123456789123456,3         123456789.1234567891234567891234567891234564  from dual;1 row created.SQL> commit;Commit completeSQL> insert into test2  select 123456789123.123456789123456789123456789123456,3         123456789123.1234567891234567891234567891234564  from dual;1 row created.SQL> commit;Commit complete.SQL> select * from test;ID                                                     ID1------------------------------------------------------- -------------------------------------------------------12.00000000000000000000000000000000000000000           12.00000000000000000000000000000000000000000012.12345678900000000000000000000000000000000           12.12350000000000000000000000000000000000000012.12345678912345678912345678912345600000000           12.12350000000000000000000000000000000000000012.12345678912345678912345678912345678912000           12.123500000000000000000000000000000000000000123456789.12345678912345678912345678912300000000000    123456789.123500000000000000000000000000000000000000123456789123.12345678912345678912345678910000000000000 #######################################################6 rows selected.

从上面测试可以看出,Scale的值是变化的,跟数据值有关系,目前看来,小数点前的数字位数和小数点后的数字位数相加为40(有时候又是39),为了测试是否这个规律,我特意用下面案例测试一下

SQL> create table test2(id number);Table created.SQL> insert into test22  select 0.123456789123456789123456789123456789123456789 from dual;1 row created.SQL> commit;Commit complete.SQL> col id for 9999999999.9999999999999999999999999999999999999999999999;SQL> select * from test2;ID----------------------------------------------------------.1234567891234567891234567891234567891235000000SQL> insert into test22  select 123456789.123456789123456789123456789123456789 from dual;1 row created.SQL> commit;Commit complete.SQL> select * from test2;ID----------------------------------------------------------.1234567891234567891234567891234567891235000000123456789.1234567891234567891234567891230000000000000000SQL> insert into test22  select 123456789123.123456789123456789123456789123456789 from dual;1 row created.SQL> commit;Commit complete.SQL> select * from test2;ID----------------------------------------------------------.1234567891234567891234567891234567891235000000123456789.1234567891234567891234567891230000000000000000##########################################################SQL>  col id for 9999999999999.9999999999999999999999999999999999999999999999;SQL> select * from test2;ID-------------------------------------------------------------.1234567891234567891234567891234567891235000000123456789.1234567891234567891234567891230000000000000000123456789123.1234567891234567891234567891000000000000000000SQL> insert into test22  select 12345678912345.12345678912345678912345678912345 from dual;1 row created.SQL> commit;Commit complete.SQL> select * from test2;ID-------------------------------------------------------------.1234567891234567891234567891234567891235000000123456789.1234567891234567891234567891230000000000000000123456789123.1234567891234567891234567891000000000000000000#############################################################SQL> col id for 9999999999999999999.99999999999999999999999999999999999999999999;SP2-0246: Illegal FORMAT string "9999999999999999999.99999999999999999999999999999999999999999999"SQL> col id for 9999999999999999999.9999999999999999999999999999999999999999SQL> select * from test2;ID-------------------------------------------------------------.1234567891234567891234567891234567891235123456789.1234567891234567891234567891230000000000123456789123.123456789123456789123456789100000000000012345678912345.1234567891234567891234567900000000000000SQL>

这个问题纠结了很久,不明白为什么是39或40,后面在Oracle Database SQL Reference 10g Release 2终于找到解释了,如下所示:

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位十进制数字,取决于小数点的位置。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值