ORACLE 中NUMBER类型默认的精度和Scale问题

简介: 在ORACLE数据库中,NUMBER(P,S)是最常见的数字类型,可以存放数据范围为10^-130~10^126(不包含此值),需要1~22字节(BYTE)不等的存储空间。P 是Precison的英文缩写,即精度缩写,表示有效数字的位数,最多不能超过38个有效数字。

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

 

clip_image001

 

当然文档没有错误,文档应该是指在定义字段数据类型为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> 

 

 

clip_image002

 

 

当在指定字段类型为NUMBER时,如果PS都不指定,那么PS又是什么值呢?今天特意实验验证了一下,具体实验过程如下:

 

 

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> 

 

 

如上所示,当我插入上面两条记录后,发现如果不指定psNUMBER类型,此时的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的值是否可以继续变大呢?

 

clip_image003

 

 

 

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位,由于格式化列的缘故,可能导致部分小数位没有显示,

 

 

clip_image004

 

我们继续测试,调整格式化列,我们发现值变为了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

 

clip_image005

 

 

继续其它测试,我们发现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.

clip_image006

 

 

从上面测试可以看出,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> 

 

clip_image007

 

 

这个问题纠结了很久,不明白为什么是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位十进制数字,取决于小数点的位置。

 

相关文章
|
2月前
|
存储 Java Apache
Python Number类型详解!
本文详细介绍了 Python 中的数字类型,包括整数(int)、浮点数(float)和复数(complex),并通过示例展示了各种算术操作及其类型转换方法。Python 的 `int` 类型支持任意大小的整数,`float` 类型用于表示实数,而 `complex` 类型用于表示复数。此外,文章还对比了 Python 和 Java 在数字类型处理上的区别,如整数类型、浮点数类型、复数类型及高精度类型,并介绍了各自类型转换的方法。尽管两种语言在语法上有所差异,但其底层逻辑是相通的。通过本文,读者可以更好地理解 Python 的数字类型及其应用场景。
60 2
|
5月前
|
存储 Oracle 关系型数据库
|
4月前
|
分布式计算 Oracle 关系型数据库
实时计算 Flink版产品使用问题之获取Oracle的数据时无法获取clob类型的数据,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
5月前
|
SQL Oracle 关系型数据库
关系型数据库Oracle备份类型
【7月更文挑战第18天】
66 2
|
6月前
|
SQL 数据采集 Oracle
实时计算 Flink版产品使用问题之如何读取oracle中的blob类型的数据
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS,数据类型概述,常见的基本数据类型有number/string/boolean/undefined/null,字符串用““,let food: string = ‘糖葫芦‘,布尔类型
TS,数据类型概述,常见的基本数据类型有number/string/boolean/undefined/null,字符串用““,let food: string = ‘糖葫芦‘,布尔类型
TS,类型注解 number就是类型注解,TS类型注解是一种为变量添加类型约束的方式,你定义什么类型,就只能赋值什么类型,变量命名规则,变量名称不能以数字开头,交换变量写法
TS,类型注解 number就是类型注解,TS类型注解是一种为变量添加类型约束的方式,你定义什么类型,就只能赋值什么类型,变量命名规则,变量名称不能以数字开头,交换变量写法
|
7月前
|
SQL Oracle 关系型数据库
实时计算 Flink版产品使用合集之使用JDBC方式读取Oracle的number类型时,通过什么方式进行映射
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
167 0
实时计算 Flink版产品使用合集之使用JDBC方式读取Oracle的number类型时,通过什么方式进行映射
|
算法
Leetcode 313. Super Ugly Number
题目翻译成中文是『超级丑数』,啥叫丑数?丑数就是素因子只有2,3,5的数,7 14 21不是丑数,因为他们都有7这个素数。 这里的超级丑数只是对丑数的一个扩展,超级丑数的素因子不再仅限于2 3 5,而是由题目给定一个素数数组。与朴素丑数算法相比,只是将素因子变了而已,解法还是和朴素丑数一致的。
104 1