oracle的number类型默认长度是多少?number默认情况下,精度为38位,取值范围1~38之间
它实际上是磁盘上的⼀个变长类型,会占⽤0~22 字节的存储空间。
只知道默认⼩数点位是0,
ORACLE NUMBER数据类型!
⽹上关于number的资料很多了,学习总结了下,如果问题及不⾜,欢迎指正。
⼀、oracle的number类型精度、刻度范围
number(p,s)
p:1---38
s:-84---127
有效数位:从左边第⼀个不为0的数算起,⼩数点和负号不计⼊有效位数。
p>0,对s分2种情况:
1. s>0
精确到⼩数点右边s位,并四舍五⼊。然后检验有效数位是否<=p;
ZWF.YUDONG>create table t_n(id number(5,2));
Table created.
ZWF.YUDONG>insert into t_n values(123.45);
1 row created.
ZWF.YUDONG>insert into t_n values(123.455);
1 row created.
ZWF.YUDONG>select * from t_n;
ID
----------
123.45
123.46
2 rows selected.
ZWF.YUDONG>insert into t_n values(1.234);
1 row created.
ZWF.YUDONG>select * from t_n;
ID
----------
123.45
123.46
1.23
3 rows selected.
ZWF.YUDONG>insert into t_n values(.001);
1 row created.
ZWF.YUDONG>select * from t_n;
ID
----------
123.45
123.46
1.23
4 rows selected.
ZWF.YUDONG>insert into t_n values(1234.56);
insert into t_n values(1234.56)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column 如果s>p,⼩数点右边⾄少有s-p个0填充。
ZWF.YUDONG>create table t_n(id number(4,5));
Table created.
ZWF.YUDONG>insert into t_n values(1);
insert into t_n values(1)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column ZWF.YUDONG>insert into t_n values(.1);
insert into t_n values(.1)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column ZWF.YUDONG>insert into t_n values(.01);
1 row created.
ZWF.YUDONG>commit;
Commit complete.
ZWF.YUDONG>select * from t_n;
ID
----------
.01
1 row selected.
ZWF.YUDONG>insert into t_n values(.001);
1 row created.
ZWF.YUDONG>insert into t_n values(.0001);
1 row created.
ZWF.YUDONG>insert into t_n values(.00001);
1 row created.
ZWF.YUDONG>insert into t_n values(.000001); --超过刻度存储0
1 row created.
ZWF.YUDONG>select * from t_n;
ID
----------
.01
.001
.0001
.00001
10 rows selected.
ZWF.YUDONG>col dp for a50
ZWF.YUDONG>select id,dump(id) dp,length(id),vsize(id) from t_n;  --vsize和dump的是字节数,length是数值实际位数(含⼩数点)      ID DP                                              LENGTH(ID)  VSIZE(ID)
---------- -------------------------------------------------- ---------- ----------
.01 Typ=2 Len=2: 192,2                                        3      2
.001 Typ=2 Len=2: 191,11                                        4      2
.0001 Typ=2 Len=2: 191,2                                        5      2
.00001 Typ=2 Len=2: 190,11                                        6      2
0 Typ=2 Len=1: 128                                            1      1
5 rows selected.
2. s<0
精确到⼩数点左边s位,并四舍五⼊。然后检验有效数位是否<=p+|s|
ZWF.YUDONG>create table t_n(id number(5,-2));
Table created.
ZWF.YUDONG>insert into t_n values(12345);
1 row created.
ZWF.YUDONG>select * from t_n;
ID
----------
12300
1 row selected.
ZWF.YUDONG>insert into t_n values(123456);
1 row created.
ZWF.YUDONG>insert into t_n values(1234567);
1 row created.
ZWF.YUDONG>select * from t_n;
ID
----------
12300
123500
1234600
3 rows selected.
ZWF.YUDONG>insert into t_n values(12345678);
insert into t_n values(12345678)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
⼆、oracle的number类型存储结构:
oracle采⽤变长存储number数据类型(按⼀定规则进⾏转换成2进制编码格式存储)。
oracle数据库中存储的number类型包含3个部分: HEAD部分, DATA部分, 符号位。
对正数来说, 符号位省略, 对0来说, oracle存储的是X80(128)。
ZWF.YUDONG>select dump(0) from dual;
DUMP(0)
----------------
Typ=2 Len=1: 128
1 row selected.
oracle四舍五入
ZWF.YUDONG>select dump(1) from dual;
DUMP(1)
-
-----------------
Typ=2 Len=2: 193,2
1 row selected.
ZWF.YUDONG>select dump(-1) from dual;
DUMP(-1)
-----------------------
Typ=2 Len=3: 62,100,102
1 row selected.
HEAD部分为⼀个字节8位, 就是前⾯看到的128, 193,62。由该部分我们可以看出number类型的基本信息,因为设计这种存储格式的时候, oracle希望以⼗六进制00-FF来表⽰所有
的number, 所以为了编码的对称, ⾸先将number分为正负, 所以以00-FF的中间位置80, 也就是⼗进制的128来表⽰0, HEAD部分⼩于80,即为负数,⼤于80即为正数。ORACLE再次对
00-80, 80-FF进⾏对分:
00-3E 表⽰: number <= -1
3F-7F 表⽰: -1 < number < 0
81-C0 表⽰: 0 < number < 1
C1-FF 表⽰:number >= 1
从HEAD部分我们可以也看出数据的位数信息,是否含有⼩数,可以根据HEAD的信息判断⼩数点的位置。由于数据部分低位2的n次⽅位个0是不被存储的,数据展现的时候oracle
根据HEAD的信息给补充末位的0。
ZWF.YUDONG>select dump(123456789) from dual;
DUMP(123456789)
------------------------------
Typ=2 Len=6: 197,2,24,46,68,90 --197(C5)的含义:表⽰数字123456789⼤于1,197-193(数字1占⽤2个字节该值为193) = 4 ,所以该数字占⽤6(2+4)个字节。
1 row selected.
然后,我们再来看数据部分, ORACLE对⼗进制的数字(整数部分,⼩数部分正好相反)是两位两位进⾏存储的(从右往左的顺序), 例如对1234, ORACLE会分别对12, 34进⾏存储.
所以只需要对(+-)1-99进⾏编码
1 --- 99 分别⽤⼗六进制2-64表⽰,就是2-100,
-1--- -99 ⽤⼗六进制64-2表⽰,就是100-2
ZWF.YUDONG>select dump(12345) from dual;
DUMP(12345)
------------------------
Typ=2 Len=4: 195,2,24,46  --数据部分2,24,46 表⽰(2-1=1,24-1=23,46-1=45);HEAD部分表⽰
12345 >= 1,占⽤195-193+2=4字节。
1 row selected.
SYS.YUDONG>select dump(1100) from dual;
DUMP(1100)
-------------------
Typ=2 Len=2: 194,12    --如果从右边起,连续2的n次⽅位为0,oracle⼀次排触(不存储)只是位数加1。可以对⽐dump(11)的情况看看。
1 row selected.
SYS.YUDONG>select dump(11) from dual;
DUMP(11)
-------------------
Typ=2 Len=2: 193,12        --这⾥数据部分和1100是⼀样的,末位的2个0没有实际存储,长度193⽐194⼩1。
1 row selected.
--对于含⼩数(负数、整数2种情况)的情况:
1、负数
SYS.YUDONG>select dump(-1.2) from dual;
DUMP(-1.2)
--------------------------
Typ=2 Len=4: 62,100,81,102 --HEAD=62(3E)表⽰该数值⼩于等于-1;数据部分:整数部分的-1存储为100,⼩数部分从左往右2位⼀结合,不⾜2位后边补⼀个1。
对应关系变为9,8...1表⽰1,2...9,看下⾯⼏个例⼦,如果⾜2位,还是按照上边说的规律(-1--- -99 ⽤⼗六进制64-2表⽰,就是100-2)。
1 row selected.
ZWF.YUDONG>select dump(-2.1) from dual;
DUMP(-2.1)
-------------------------
Typ=2 Len=4: 62,99,91,102
1 row selected.
ZWF.YUDONG>select dump(-2.2) from dual;
DUMP(-2.2)
-------------------------
Typ=2 Len=4: 62,99,81,102
1 row selected.
ZWF.YUDONG>select dump(-2.9) from dual;
DUMP(-2.9)
-------------------------
Typ=2 Len=4: 62,99,11,102
1 row selected.
ZWF.YUDONG>select dump(-2.12) from dual;
DUMP(-2.12)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。