在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#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 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,我们继续测试,插入下面数据

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的值是否可以继续变大呢?

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位吗?

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的值会随着小数点前面数字的变化而变化,如下所示:

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),为了测试是否这个规律,我特意用下面案例测试一下

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终于找到解释了,如下所示:

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

转载于:https://www.cnblogs.com/kerrycode/p/6957574.html

ORACLE 中NUMBER类型默认的精度和Scale问题相关推荐

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

    在ORACLE数据库中,NUMBER(P,S)是最常见的数字类型,可以存放数据范围为10^-130~10^126(不包含此值),需要1~22字节(BYTE)不等的存储空间.P是Precison的英文缩 ...

  2. Oracle中NUMBER类型如果不指定长度和小数点精度默认是多长

    http://otvety.google.ru/otvety/thread?tid=46ed8b35f29d2640 在Oracle中Number类型可以用来存储0,正负定点或者浮点数,可表示的数据范 ...

  3. oracle 定义小数,Oracle中NUMBER类型如果不指定长度和小数点精度默认是多长

    在Oracle中Number类型可以用来存储0,正负定点或者浮点数,可表示的数据范围在 1.0 * 10(-130) -- 9.9...9 * 10(125) {38个9后边带88个0} 的数字,当O ...

  4. Oracle中Number类型字段使用.netTiers和CodeSmith问题的解决方案

    在oracle中字段类型为Number(m, n)时,使用codesmith+.nettiers模板生成代码,发现m和n值被指定值后,访问数据时引发数据类型转换异常.目前的解决方案是,仅指定数据类型为 ...

  5. oracle精度制的数据类型,ORACLE 中NUMBER 类型 低精度转换成高精度

    Node.js的函数返回值 先看一段代码: function select(sqlscript){     var result = "";     sql.connect(con ...

  6. Spark SQL读取Oracle的number类型的数据时精度丢失问题

    Spark SQL读取Oracle的number类型的数据时精度丢失问题 在程序开发中,使用到了sparkSQL读取Oracle数据库,发现当sparkSQL读取Oracle的number类型字段时, ...

  7. oracle中varchar2类型的字段长度单位默认是按照byte来定义

    1.背景 使用oracle时,会这样忽略一个问题:oracle中varchar2类型的字段长度单位不指定类型时,按照byte来定义. 如果数据库使用的字符集是GBK,GB2312或者其他定长字符集的话 ...

  8. ORACLE中date类型字段的处理

    ORACLE中date类型字段的处理 (1)在英文版本的ORACLE中默认日期格式为'DD-MON-YY',例如'01-JAN-98' 在汉化的中文版本中ORACLE默认日期格式为'日-月-年',例如 ...

  9. oracle 日期 区别,oracle中日期类型 to_date 和to_timestamp什么区别啊?

    1.to_date() 和to_timestamp()区别 由于oracle中date类型只支持到秒,不支持到毫秒,所以to_date()不能取到毫秒.如果要取到毫秒,oracle 9i以上版本,可以 ...

最新文章

  1. Loj #3111. 「SDOI2019」染色
  2. 正则表达式——常用元字符
  3. haxm intel庐_Android Studio中Intel HAXM的那些坑
  4. 【知乎摘要】女生婚前应该清楚男友哪些方面了才能嫁给他
  5. linux常用命令 打开文件,【Linux】常用命令 lsof查看打开的文件
  6. YUI事件体系之Y.Do
  7. m40型工业机器人_工业机器人选型的9大参数
  8. 官方:Angular 5 推迟到10月底发布
  9. 全国程序员工资最新统计来了,平均 14,542 元!
  10. android 切换主题介绍一
  11. 远程Redis服务器 JedisConnectionException: Failed connecting to host localhost:6379 解决方案
  12. MP2315高频同步整流降压x芯片电路原理图
  13. linux在命令行下打开pdf文件
  14. 新浪微博开放平台第三方登陆请求授权出现错误码:21322(重定向地址不匹配)的解决方法
  15. 奖励补贴有点多!武汉市大健康和生物技术产业发展奖励措施解读
  16. 互联网创业公司的管理
  17. 格密码LLL算法:如何解决最短向量SVP问题(3)(完结篇)
  18. 不得不知道的搜索引擎使用技巧(思维导图版)
  19. xctf-HTTP通常使用两种请求方法
  20. 想知道会议录音转文字怎么转吗?这篇文章告诉你

热门文章

  1. Latent Semantic Analysis (LSA) Tutorial第一部分(转载)
  2. 数据库服务器修改地址,数据库服务器修改地址吗
  3. 基于jQuery的窗口插件:jMessageBox
  4. spring包装hibernate_全网最全Spring系列面试题129道(附答案解析)
  5. python 线程池_python线程池
  6. virtual box和vmware有什么区别吗_真发假发套与普通假发有什么区别吗?
  7. QUIC/UDT/SRT
  8. SQL那些事儿(十二)--DATASET 与 DATAREADER区别
  9. 设置和使用地图的范围—ArcGIS API for JavaScript
  10. 网游服务端开发入门知识