oracle dump 函数关键字: dumpdump函数(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进制,单字符。 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 |
|