ITPub博客

首页 > Linux操作系统 > Linux操作系统 > ORACLE数字算法

ORACLE数字算法

原创 Linux操作系统 作者:gaopengtttt 时间:2013-03-19 12:01:32 0 删除 编辑
创建一个表
SQL> create table testpp
  2  (it number);
 
Table created
 
SQL> insert into testpp
  2  values(100);
 
1 row inserted
计算器块
SQL> select rowid from testpp;
 
ROWID
------------------
AAAXKYAABAAAU4aAAA
 
SQL> select dbms_rowid.rowid_relative_fno('AAAXKYAABAAAU4aAAA'),dbms_rowid.rowid_block_number('AAAXKYAABAAAU4aAAA') from testpp;
 
DBMS_ROWID.ROWID_RELATIVE_FNO( DBMS_ROWID.ROWID_BLOCK_NUMBER(
------------------------------ ------------------------------
                             1                          85530
进行DUMP
SQL> alter system dump datafile 1 block 85530;
 
System altered
查看其数字的dump格式
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f9a
avsp=0x1f83
tosp=0x1f83
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f9a
block_row_dump:
tab 0, row 0, @0x1f9a
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c2 02  ----这里就是DUMP出来的,长度是2
end_of_block_dump
End dump data blocks tsn: 0 file#: 1 minblk 85530 maxblk 85530
其实这里的C2 02就是其具体的数字。使用DUMP函数也能得出
SQL> select dump(it,16) from testpp;
 
DUMP(IT,16)
--------------------------------------------------------------------------------
Typ=2 Len=2: c2,2
然后通过ORACLE的算法计算回去
SQL> select to_number('c2','xxxx') from dual;
 
TO_NUMBER('C2','XXXX')
----------------------
                   194
 
SQL> select to_number('2','xxxx') from dual;
 
TO_NUMBER('2','XXXX')
---------------------
                    2
 其实这里的如果换算为10进制是
194,2
如果大于128 就是正数,小于128就是负数
指数是194-193=1
数字位1 是2-1=1*100^(1-0)=100 -1是因为正数+1存储
所以数字也就还原为100
SQL> select (to_number('2','xxxx')-1)*power(100,to_number('c2','xxxx')-193) from dual;
 
(TO_NUMBER('2','XXXX')-1)*POWE
------------------------------
                           100
用SQL就是这样,这是第一位
在加入一个负数
SQL> insert into test
  2  values(-123.333);
 
1 row inserted
 
SQL> commit;
 
Commit complete
进行DUMP如上
tab 0, row 1, @0x1f90
tl: 10 fb: --H-FL-- lb: 0x2  cc: 1
col  0: [ 6]  3d 64 59 59 47 66
进行计算
Typ=2 Len=6: 3d,64,59,59,47,66
SQL> select dump(it,16) from testpp;
 
DUMP(IT,16)
--------------------------------------------------------------------------------
Typ=2 Len=2: c2,2
Typ=2 Len=6: 3d,64,59,59,47,66  --66 及10进制的102是一个排序位不用理会,用在负数的时候
内部存储长度6 指数3d 后面数数字位
换算为10进制就是
61,100,89,89,71,102
61是指数未
102 是排序位
中间的数字位
select -((101 - to_number('64', 'xxxx')) *
       power(100, 62 - to_number('3d', 'xxxx')) +
       (101 - to_number('59', 'xxxx')) *
       power(100, 62 - to_number('3d', 'xxxx') - 1) +
       (101 - to_number('59', 'xxxx')) *
       power(100, 62 - to_number('3d', 'xxxx') - 2) +
       (101 - to_number('47', 'xxxx')) *
       power(100, 62 - to_number('3d', 'xxxx') - 3) )
  from dual;
这样数字就完成的转换。
 
下面来自网络:

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的情况。
 
现在再考虑一下为什么在最后加102是为了排序的需要,-123456.789在数据库中实际存储为

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7728585/viewspace-756508/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: UNDO 分配过程
请登录后发表评论 登录
全部评论
wxh gp_22389860 公众号 MySQL学习 书籍 深入理解MySQL主从原理

注册时间:2021-06-07

  • 博文量
    868
  • 访问量
    3495554