日期:2014-05-16  浏览次数:20683 次

Oracle 数据类型及存储方式(二)数值类型

第二部分 数值类型
§ 2.1 number
Number类型是oralce的数值类型,存储的数值的精度可以达到38位。Number是一种变长类型,长度为0-22字节。取值范围为:10e- 130 – 10e 126(不包括)
Number(p,s)
P和s都是可选的。
P指精度(precision),即总位数。默认情况下精度为38。精度的取值范围为1~38.
S指小数位(scale).小数点右边的位数。小数点位数的合法值为-48~127。小数位的默认值由精度来决定。如果没有指定精度,小数位默认为最大的 取值区间.如果指定了精度,没有指定小数位。小数位默认为0(即没有小数位).
精度和小数位不会影响数据如何存储,只会影响允许哪些数值及数值如何舍入。


1.新建一个表
SQL> create table test_number(col_number number(6,2));

Table created
2.插入一些不同的数据
SQL> insert into test_number values(-1);

1 row inserted

SQL> insert into test_number values(0);

1 row inserted

SQL> insert into test_number values(1);

1 row inserted

SQL> insert into test_number values(2);

1 row inserted

SQL> insert into test_number values(11.00);

1 row inserted

SQL> insert into test_number values(11.11);

1 row inserted

SQL> insert into test_number values(1234.12);

1 row inserted

SQL> insert into test_number values(-0.1);

1 row inserted

SQL> insert into test_number values(-11.11);

1 row inserted

SQL> insert into test_number values(-1234.12);

1 row inserted
SQL> commit;

Commit complete

3.查看结果
SQL> select * from test_number;

COL_NUMBER
----------
???? -1.00
????? 0.00
????? 1.00
????? 2.00
???? 11.00
???? 11.11
?? 1234.12
???? -0.10
??? -11.11
-1234.12

10 rows selected

5. 查看存储结构
SQL> select col_number, dump(col_number) from test_number;

COL_NUMBER DUMP(COL_NUMBER)
---------- --------------------------------------------
???? -1.00 Typ=2 Len=3: 62,100,102
????? 0.00 Typ=2 Len=1: 128
????? 1.00 Typ=2 Len=2: 193,2
????? 2.00 Typ=2 Len=2: 193,3
???? 11.00 Typ=2 Len=2: 193,12
???? 11.11 Typ=2 Len=3: 193,12,12
?? 1234.12 Typ=2 Len=4: 194,13,35,13
???? -0.10 Typ=2 Len=3: 63,91,102
??? -11.11 Typ=2 Len=4: 62,90,90,102
-1234.12 Typ=2 Len=5: 61,89,67,89,102

10 rows selected

由此可见:
Number类型的内部编码为:2
根据每一行的len值可以看出,number是一个变长类型。不同的数值占用不同的空间。
如果指定了精度,显示结果与精度相关。
就像我插入语句写为
insert into test_number values(0);
但是显示结果为:0.00
如果数值是负数,在最后一位上填充一个补码102.即表示该数值为负数。
0是一个特殊的值,它在oracle中存储为128.
第一位为标志位。以128为比较。如果数值大于128,则它大于0。如果小于128小于0。
-1的内部存储为:
-1.00 Typ=2 Len=3: 62,100,102
最后一位是102,是一个负数。
第一位小于128,所以小于10.
除了第一位标志位外,其它的都是数值为了。
如果该值是一个正数。每一位的存储值减1为每一位的实际值。
1.0的存储结构为:
1.00 typ=2 Len=2: 193,2
实值上1.00的存储结果与1相同。
第一位193为标志位,大于128,大于0.
第二位为数值为,因为是正数,实际值为存储值减1。2-1 = 1。
如是该值是一个负数,每一位的实际值为101 减去存储的值。
-1.00的存储结构为:
-1.00 Typ=2 Len=3: 62,100,102
最后一位102为补位。
第一位62为标志位,小于128。实际值小于0.
第二位为数值为,因为是负数。实际值为:101 – 100 =1.

§2.2 小数位在哪里?
从上面的存储结果看,对小数存储时,它并没有一个小数的标志位。但是它实际上是由第一位标志位,和数值位(第二位)来决定的。
当存储的数是一个正数,该数值的前几位为:第一位 * power(100 , (标志位 - 193));
当存储的数是一个负数,该数值的前几位为:第一位 * power(100,(62 – 标志位));
11.11的存储结果为:
11.11 Typ=2 Len=3: 193,12,12
第一位数值位为:12 实际数值为11
标志位为:193
12 * power(100, (193- 193);
?? 100的零次方为1.
12 乘1 等于12.
所以这个数的前几位为:12。从这后面就是小数了。
1234.12的存储结构为:
1234.12 Typ=2 Len=4: 194,13,35,13
第一位数值位为:13,实际值为12
标志位为:193
13 * power(100,(194-193)) = 1300
所以前四位为整数位,后面的为小数位。


-0.10的存储结构为:
-0.10 Typ=2 Len=3: 63,91,102
标志位为:63
第一位数值为:91 ,实际值为:10
91 * (100,(62-63)) =-9100.
所以小数位在91之前。

-1234.12的存储结构为:
-1234.12 Typ=2 Len=5: 61,89,67,89,102
标志位为:61
第一位数值为:89
89*(100,(62-61)) =8900
所以小数位在67之后。
§2.3 number的精度和小数位
Number类型的精度最多可是38位。小数位-84--127位。
SQL> create table test_number1(col_number number(39));

create table test_number1(col_number number(39))

ORA-01727: numeric precision specifier is out of range (1 to 38) <