-
dump函数(number类型) 笔记
-
dump 函数能查看表中列在datafile存储内容。
-
Oracle的NUMBER类型最多由三个部分构成,这三个部分分别是最高位表示位、数据部分、符号位。其中负数包含符号位,正数不会包括符号位(10进制即102)。另外,数值0比较特殊,它只包含一个数值最高位表示位80(16进制),没有数据部分。
-
-
用法:DUMP(expr[,number_format[,start_position][,length]])
-
-
用法说明: dump(col_name,8|10|16|17) ,其中8|10|16|17 为number_format,分别为8进制,10进制(默认值),16进制,单字符。
-
-
The syntax is:
-
DUMP(expr[,return_fmt[,start_position[,length]]])
-
The argument return_fmt specifies the format of the return value and can have any of the following values:
-
8 returns result in octal notation.
-
10 returns result in decimal notation.
-
16 returns result in hexadecimal notation.
-
17 returns result as single characters.
-
By default, the return value contains no character set information. To retrieve the character set name of expr, specify any of the preceding format values, plus 1000. For example, a return_fmt of 1008 returns the result in octal, plus provides the character set name of expr.
-
The arguments start_position and length combine to determine which portion of the internal representation to return. The default is to return the entire internal representation in decimal notation.
-
If expr is null, then this function returns a null.
-
-
-
DUMP函数的输出格式类似:
-
-
类型 <[长度]>,符号/指数位 [数字1,数字2,数字3,......,数字20]
-
-
各位的含义如下:
-
-
1.类型: Number型,Type=2 (类型代码可以从Oracle的文档上查到,见结尾)
-
-
2.长度:指存储的字节数
-
-
3.符号/指数位
-
-
在存储上,Oracle对正数和负数分别进行存储转换:
-
-
正数:加1存储(为了避免Null),在实际算法中就是要减1,必须>128
-
负数:被101减,如果总长度小于21个字节,最后加一个102(是为了排序的需要),必须<128
-
-
指数位换算:
-
-
正数:指数=符号/指数位 - 193 (第一字节)
-
负数:指数=62 - 第一字节
-
-
4.从<数字1>开始是有效的数据位
-
-
从<数字1>开始是最高有效位,所存储的数值计算方法为:
-
-
将下面计算的结果加起来:
-
-
每个<数字位>乘以100^(指数-N) (N是有效位数的顺序位,第一个有效位的N=0)
-
-
===numbe类型例子====
-
例1:(区别正数和负数)
-
SQL> select dump(0) from dual;
-
-
DUMP(0)
-
--------------------------------
-
Typ=2 Len=1: 128
-
##
-
例1中可以看见,为什么>128断定为正数,而<128 断定为负数(10进制)
-
-
## 16进制分析正数和负数
-
SQL> select dump(0,16) from dual;
-
-
DUMP(0,16)
-
------------------------------
-
Typ=2 Len=1: 80--------------------(只有高位)
-
-
1 row selected.
-
-
DUMP(0) 的结果是0x80,在前面已经提到,0只有高位表示位,没有数据位。由于0的特殊,既不属于正数,也不属于负数,因此使用高位表示位用80表示就足够了, 不会和其它数据冲突,Oracle出于节省空间的考虑将后面数据部分省掉了。但是为什么Oracle选择0x80表示0呢?我们知道正数和负数互为相反 数,每个正数都有一个对应的负数。因此如果我们要使用编码表示数值,则表示正数和负数的编码应该各占一半,这样才能保证使Oracle表示数据范围是合理的。而0x80的二进制编码是1000 0000,正好是一个字节编码最大值的一半,因此,Oracle选择0x80来表示0,是十分有道理的。
-
-
-
@@@@
-
-
例2:(正数)
-
SQL> select dump(1,10) from dual;
-
-
DUMP(1,10)
-
------------------------------------
-
Typ=2 Len=2: 193,2
-
| |
-
高位,数据部分
-
-
-
1 row selected.
-
-
##
-
SQL> select dump(1) from dual;
-
-
DUMP(1)
-
------------------------------------
-
Typ=2 Len=2: 193,2
-
-
1 row selected.
-
##
-
例2中可以看见dump(1,10)和dump(1) 输出结果一样:Typ=2 Len=2: 193,2
-
类型是number,2字节,因为正数所以>128,因为正数所以存储时候都+1
-
-
<指数>: 193 - 193 = 0
-
<数字1> 2 - 1 = 1 *100^(0-0)
-
= 1
-
-
@@@@@@@@
-
例3:(正数指数变化)
-
SQL> select dump(99) from dual;
-
-
DUMP(99)
-
----------------------------------------
-
Typ=2 Len=2: 193,100
-
-
1 row selected.
-
-
-
##
-
-
SQL> select dump(100) from dual;
-
-
DUMP(100)
-
------------------------------------
-
Typ=2 Len=2: 194,2
-
-
1 row selected.
-
-
例3对比就知道,第一字节指数从193变化到194
-
-
@@@@@@@@@@@
-
-
例4:(负数)
-
SQL> select dump(-98) from dual;
-
-
DUMP(-98)
-
------------------------------------------
-
Typ=2 Len=3: 62,3,102
-
| | |
-
高位,数据部分,符号位
-
-
-
-
-
-
1 row selected.
-
<指数> 62 - 62 = 0
-
<数字1> 101 - 3 = 98 *100^(0-0)
-
= 98
-
-
##
-
SQL> select dump(-99) from dual;
-
-
DUMP(-99)
-
------------------------------------------
-
Typ=2 Len=3: 62,2,102
-
-
1 row selected.
-
-
<指数> 62 - 62 = 0
-
<数字1> 101 - 2 = 99 *100^(0-0)
-
= 99
-
-
-
-
-
###
-
SQL> select dump(-100) from dual;
-
-
DUMP(-100)
-
----------------------------------------------
-
Typ=2 Len=3: 61,100,102
-
-
1 row selected
-
-
最后加102是目的:
-
实际存储中-98 为62,3
-
-99 为62,2
-
-100为61,100
-
-
得知-98>-99>-100
-
-
但是如果
-
SQL> select dump(-98.001) from dual;
-
-
DUMP(-98.001)
-
--------------------------------------------------------
-
Typ=2 Len=5: 62,3,101,91,102
-
-
1 row selected.
-
-
通过这个得知 没有102:-98.001为 62,3,101,91 >-98 为62,3
-
-
有102:-98.001为 62,3,101,91,102
-
-98 为 62,3,102
-
-
-
所以加102目的是排序的需要!
-
-
-
例5:(数字位算法)
-
SQL> select dump(7654321) from dual;
-
-
DUMP(7654321)
-
------------------------------------------------------
-
Typ=2 Len=5: 196,8,66,44,22
-
-
1 row selected.
-
-
<指数>: 196 - 193 = 3
-
<数字1> 8 - 1 = 7 *100^(3-0) 7000000
-
<数字2> 66 - 1 = 65 *100^(3-1) 650000
-
<数字3> 44 - 1 = 43 *100^(3-2) 4300
-
<数字4> 22 - 1 = 21 *100^(3-3) 21
-
-
##
-
SQL> select dump(87654321) from dual;
-
-
DUMP(87654321)
-
--------------------------------------------------------
-
Typ=2 Len=5: 196,88,66,44,22
-
-
1 row selected.
-
-
-
-
<指数>: 196 - 193 = 3
-
<数字1> 88 - 1 = 87 *100^(3-0) 87000000
-
<数字2> 66 - 1 = 65 *100^(3-1) 650000
-
<数字3> 44 - 1 = 43 *100^(3-2) 4300
-
<数字4> 22 - 1 = 21 *100^(3-3) 21
-
-
-
-
-
×××××××××××××××
-
类型代码(参考)
-
代码 数据类型 oracle 版本
-
1 varchar2 7
-
2 number 7
-
8 long 7
-
12 date 7
-
23 raw 7
-
24 long raw 7
-
69 rowid 7
-
96 char 7
-
112 clob 8
-
113 blob 8
-
114 bfile 8
-
180 timestamp 9i
-
181 timestamp with timezone 9i
-
182 interval year to month 9i
-
183 interval day to second 9i
-
208 urowid 8i
-
231 timestamp with local timezone 9i
-
-
-
****************************************************************
-
****************************************************************
-
Oracle在数据库内部通过相应的算法转换来进行数据存储,本文简单介绍Oracle的Number型数值存储及转换.
-
我们可以通过DUMP函数来转换数字的存储形式,一个简单的输出类似如下格式:
-
SQL> select dump(1) from dual;
-
DUMP(1)
-
------------------
-
Typ=2 Len=2: 193,2
-
DUMP函数的输出格式类似:
-
类型 <[长度]>,符号/指数位 [数字1,数字2,数字3,......,数字20]
-
各位的含义如下:
-
1.类型: Number型,Type=2 (类型代码可以从Oracle的文档上查到)
-
2.长度:指存储的字节数
-
3.符号/指数位
-
在存储上,Oracle对正数和负数分别进行存储转换:
-
正数:加1存储(为了避免Null)
-
负数:被101减,如果总长度小于21个字节,最后加一个102(是为了排序的需要)
-
指数位换算:
-
正数:指数=符号/指数位 - 193 (最高位为1是代表正数)
-
负数:指数=62 - 第一字节
-
4.从<数字1>开始是有效的数据位
-
从<数字1>开始是最高有效位,所存储的数值计算方法为:
-
将下面计算的结果加起来:
-
每个<数字位>乘以100^(指数-N) (N是有效位数的顺序位,第一个有效位的N=0)
-
5. 举例说明
-
-
SQL> select dump(123456.789) from dual;
-
DUMP(123456.789)
-
-------------------------------
-
Typ=2 Len=6: 195,13,35,57,79,91
-
-
<指数>: 195 - 193 = 2
-
<数字1> 13 - 1 = 12 *100^(2-0) 120000
-
<数字2> 35 - 1 = 34 *100^(2-1) 3400
-
<数字3> 57 - 1 = 56 *100^(2-2) 56
-
<数字4> 79 - 1 = 78 *100^(2-3) .78
-
<数字5> 91 - 1 = 90 *100^(2-4) .009
-
123456.789
-
-
SQL> select dump(-123456.789) from dual;
-
DUMP(-123456.789)
-
----------------------------------
-
Typ=2 Len=7: 60,89,67,45,23,11,102
-
-
<指数> 62 - 60 = 2(最高位是0,代表为负数)
-
<数字1> 101 - 89 = 12 *100^(2-0) 120000
-
<数字2> 101 - 67 = 34 *100^(2-1) 3400
-
<数字3> 101 - 45 = 56 *100^(2-2) 56
-
<数字4> 101 - 23 = 78 *100^(2-3) .78
-
<数字5> 101 - 11 = 90 *100^(2-4) .009
-
123456.789(-)
-
现在再考虑一下为什么在最后加102是为了排序的需要,-123456.789在数据库中实际存储为
-
60,89,67,45,23,11
-
而-123456.78901在数据库中实际存储为
-
60,89,67,45,23,11,91
-
可见,如果不在最后加上102,在排序时会出现-123456.789<-123456.78901的情况。
-
NUMBER数字类型为什么有2个字节的长度呢?
-
对于这个问题,我想我们应该知道,所有数据类型最终在计算机里都以二进制存储,实际上所谓的数据类型都是我们定义的.所以存储只由算法决定.
-
所以这个问题是不成立的.比如:
-
-
SQL> select dump(110) from dual;
-
DUMP(110)
-
---------------------
-
Typ=2 Len=3: 194,2,11
-
SQL> select dump(1100) from dual;
-
DUMP(1100)
-
-------------------
-
Typ=2 Len=2: 194,12
-
-
我们会看到,虽然1100>110,但是存储上1100却只占2字节,而110却占了3个字节.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28878983/viewspace-2137517/
,如需转载,请注明出处,否则将追究法律责任。