楼主: d.c.b.a

研究Oracle 8i的block结构,提供两个未写完的程序.

[复制链接]
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
11#
 楼主| 发表于 2005-1-10 09:19 | 只看该作者

Convert Number to string.

// Convert Data Bytes to String
        // Oracle TYPE_ID = 2
        public String convertNUMBER(byte buf[],int start,int len)
        {
                int num_sign    = ((int)0x80 & buf[start]) >> 7;
                int digit_count = ((int)0xff & buf[start]);
                if (num_sign == 0x01 && digit_count == 0x80)
                        return "0";
                StringBuffer temp = new StringBuffer();
                if (num_sign == 0x01)
                        digit_count = digit_count - 0xc0;
                else
                        digit_count = 0x40 - digit_count - 1;
                if (num_sign == 0)
                {
                        temp.append("-";
                        if (digit_count <= 0)
                                temp.append("0.";
                        for(int i = 0; i > digit_count;i--)
                                temp.append("00";
                        for(int i=start+1;i<start+len-1;i++)
                        {
                                if ( 101 - ((int)0xff & buf) < 10)
                                        temp.append("0";
                                temp.append(101 - ((int)0xff & buf));
                                if (i - start == digit_count && i - start != len - 1)
                                        temp.append(".";
                        }
                        for(int i = 0; i < digit_count - len + 1;i++)
                                temp.append("00";
                }
                else
                {
                        if (digit_count <= 0)
                                temp.append("0.";
                        for(int i = 0; i > digit_count;i--)
                                temp.append("00";
                        for(int i=start+1;i<start+len;i++)
                        {
                                if (((int)0xff & buf) - 1 < 10)
                                        temp.append("0";
                                temp.append(((int)0xff & buf) - 1);
                                if (i - start == digit_count && i - start != len - 1)
                                        temp.append(".";
                        }
                        for(int i = 0; i < digit_count - len + 1;i++)
                                temp.append("00");
                }
                return temp.toString();
        }

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
12#
 楼主| 发表于 2005-1-10 09:23 | 只看该作者
Number test

numtest.txt

1.44 KB, 下载次数: 30

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
13#
 楼主| 发表于 2005-1-10 09:27 | 只看该作者
Read Cluster Block

clustertest.txt

1.56 KB, 下载次数: 28

使用道具 举报

回复
论坛徽章:
5
授权会员
日期:2005-10-30 17:05:33生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:532015年新春福章
日期:2015-03-04 14:19:112015年新春福章
日期:2015-03-06 11:57:31
14#
发表于 2005-1-10 09:49 | 只看该作者
最初由 d.c.b.a 发布
[B]number的存贮我已经搞清楚了,不过发现Oracle存贮负数时浪费了一个字节,最后一个字节总是102. [/B]


没看程序,但是还是很PF。希望有一天能看到non-oracle写的xxDUL出来。

负数的长度小于21 byte时,最后会加上102,是为了排序的需要。

HIH!

使用道具 举报

回复
论坛徽章:
25
ITPUB元老
日期:2005-02-28 12:57:00咸鸭蛋
日期:2013-02-07 11:51:42咸鸭蛋
日期:2013-02-08 09:48:51蜘蛛蛋
日期:2013-02-21 15:47:392013年新春福章
日期:2013-02-25 14:51:24咸鸭蛋
日期:2013-02-28 17:08:42蜘蛛蛋
日期:2013-03-29 16:17:14双黄蛋
日期:2013-04-11 16:11:04咸鸭蛋
日期:2013-05-07 11:55:14咸鸭蛋
日期:2013-05-28 10:46:24
15#
发表于 2005-1-11 16:52 | 只看该作者

Re: Convert Number to string.

老兄的算法是错误的,你并没有彻底理解number的格式
它是类似100进制的
first byte first bit是数的符号,后面7bit是幂,幂本身还后正负,第一字节可能是ff,你怎么处理?也可能是00
幂不是digit count,那样的化可能有125+40个了
最初由 d.c.b.a 发布
[B]// Convert Data Bytes to String
        // Oracle TYPE_ID = 2
        public String convertNUMBER(byte buf[],int start,int len)
...                        for(int i = 0; i < digit_count - len + 1;i++)
                                temp.append("00";
                }
                return temp.toString();
        } [/B]

使用道具 举报

回复
论坛徽章:
25
ITPUB元老
日期:2005-02-28 12:57:00咸鸭蛋
日期:2013-02-07 11:51:42咸鸭蛋
日期:2013-02-08 09:48:51蜘蛛蛋
日期:2013-02-21 15:47:392013年新春福章
日期:2013-02-25 14:51:24咸鸭蛋
日期:2013-02-28 17:08:42蜘蛛蛋
日期:2013-03-29 16:17:14双黄蛋
日期:2013-04-11 16:11:04咸鸭蛋
日期:2013-05-07 11:55:14咸鸭蛋
日期:2013-05-28 10:46:24
16#
发表于 2005-1-11 17:14 | 只看该作者
算法应该是这样的,最后20byte简单,我不说了,算出来全是小数点后的数字

第一字节很重要,
1st bit, 如果是1,则后面-1,如果是0则后面的数字被101减
1st bit 如果是1,把后面7bit变反,然后再看2nd bit如果还是1,在把后面6bit变反,最后7bit看做是7bit的补码,也是是它是有正负的
把最后得到得7bit补码乘100就是这个数得值,最后应该是

0.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*100^m
数字最多40位,m是7bit补码,范围是-64~63=>10^-128~10^126

使用道具 举报

回复
论坛徽章:
60
2007年度最佳版主
日期:2008-04-03 16:46:15现任管理团队成员
日期:2011-05-07 01:45:08双黄蛋
日期:2011-06-15 17:03:34ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
17#
发表于 2005-1-13 19:13 | 只看该作者
AnySQL 如果能吸引更多的人用开源模式开发就很棒了

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
18#
 楼主| 发表于 2005-1-14 16:25 | 只看该作者

下面这一段,是对的了


  1.         // Convert Data Bytes to String
  2.         // Oracle TYPE_ID = 2
  3.         public String convertNUMBER(byte buf[],int start,int len)
  4.         {
  5.                 int num_sign    = ((int)0x80 & buf[start]) >> 7;
  6.                 int digit_count = ((int)0xff & buf[start]);
  7.                 if (num_sign == 0x01 && digit_count == 0x80)
  8.                         return "0";
  9.                 temp.delete(0,temp.length());
  10.                 if (num_sign == 0x01)
  11.                         digit_count = digit_count - 0xc0;
  12.                 else
  13.                         digit_count = 0x40 - digit_count - 1;
  14.                 if (num_sign == 0)
  15.                 {
  16.                         //temp.append("-");
  17.                         if (digit_count <= 0)
  18.                                 temp.append("0.");
  19.                         for(int i = 0; i > digit_count;i--)
  20.                                 temp.append("00");
  21.                         for(int i=start+1;i<start+len-(len < 21?1:0) & i < _block_size-4;i++)
  22.                         {
  23.                                 if ( 101 - ((int)0xff & buf[i]) < 10 && temp.length() > 0)
  24.                                         temp.append("0");
  25.                                 temp.append(101 - ((int)0xff & buf[i]));
  26.                                 if (i - start == digit_count && i - start != len-1-(len<21?1:0))
  27.                                         temp.append(".");
  28.                         }
  29.                         for(int i = 0; i < digit_count - len + (len == 21?1:0);i++)
  30.                                 temp.append("00");
  31.                 }
  32.                 else
  33.                 {
  34.                         if (digit_count <= 0)
  35.                                 temp.append("0.");
  36.                         for(int i = 0; i > digit_count;i--)
  37.                                 temp.append("00");
  38.                         for(int i=start+1;i<start+len & i < _block_size - 4;i++)
  39.                         {
  40.                                 if (((int)0xff & buf[i]) - 1 < 10 && temp.length() > 0)
  41.                                         temp.append("0");
  42.                                 temp.append(((int)0xff & buf[i]) - 1);
  43.                                 if (i - start == digit_count && i - start != len - 1)
  44.                                         temp.append(".");
  45.                         }
  46.                         for(int i = 0; i < digit_count - len + 1;i++)
  47.                                 temp.append("00");
  48.                 }
  49.                 return (num_sign==0 ? "-":"" )+ temp.toString();
  50.         }
复制代码

使用道具 举报

回复
论坛徽章:
42
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:022011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23
19#
 楼主| 发表于 2005-1-14 16:26 | 只看该作者

打印出一条记录的函数printRow


  1.         public final void printRow(int row_offset,boolean deleted)
  2.         {
  3.                 int zero = 0xff;
  4.                 int pos = 0;

  5.                 record_buffer.delete(0,record_buffer.length());

  6.                 // The first byte is record flag
  7.                 // The second byte is trans slot id
  8.                 // The third is the column count
  9.                 int field_count = (int)(zero & _block_buf[row_offset+2]);
  10.                 int row_length  = 0;
  11.                 pos = row_offset+3;

  12.                 // Skip Cluster Key Byte
  13.                 if (getTableCount()>1)
  14.                         pos ++;

  15.                 if ((ROW_LAST_PIECE & _block_buf[row_offset]) != ROW_LAST_PIECE ||
  16.                         (ROW_CONTINUE_NEXT & _block_buf[row_offset]) == ROW_CONTINUE_NEXT)
  17.                 {
  18.                         pos = pos + 6;
  19.                 }

  20.                 for (int i=0;i<field_count;i++)
  21.                 {
  22.                         row_length = (int)(zero & _block_buf[pos]);
  23.                         pos = pos + 1;
  24.                         if (i > 0)
  25.                                 record_buffer.append(",");
  26.                         if (row_length == 0xff) //Middle null column
  27.                         {
  28.                                 //_output_file.print(0);
  29.                         }
  30.                         else if (row_length == 0xfe) // Field > 254 bytes
  31.                         {
  32.                                 row_length = (zero & _block_buf[pos]) +
  33.                                         ((zero & _block_buf[pos + 1]) << 8);
  34.                                 pos = pos + 2;
  35.                                 if (_column_type == null || i >= _column_type.length)
  36.                                         record_buffer.append(convertRAW(_block_buf,pos,row_length));
  37.                                 else
  38.                                 {
  39.                                         switch(_column_type[i])
  40.                                         {
  41.                                                 case ORACLE_VARCHAR2:
  42.                                                 case ORACLE_VARCHAR:
  43.                                                 case ORACLE_LONG:
  44.                                                         record_buffer.append(convertVARCHAR(_block_buf,pos,row_length));
  45.                                                         break;
  46.                                                 case ORACLE_CHAR:
  47.                                                         record_buffer.append(convertCHAR(_block_buf,pos,row_length));
  48.                                                         break;
  49.                                                 case ORACLE_NUMBER:
  50.                                                         record_buffer.append(convertNUMBER(_block_buf,pos,row_length));
  51.                                                         break;
  52.                                                 case ORACLE_DATE:
  53.                                                         record_buffer.append(convertDATE(_block_buf,pos,row_length));
  54.                                                         break;
  55.                                                 default:
  56.                                                         record_buffer.append(convertRAW(_block_buf,pos,row_length));
  57.                                                         break;
  58.                                         }
  59.                                 }
  60.                                 pos = pos + row_length;
  61.                         }
  62.                         else // Field < 254 bytes
  63.                         {
  64.                                 if (_column_type == null || i >= _column_type.length)
  65.                                         record_buffer.append(convertRAW(_block_buf,pos,row_length));
  66.                                 else
  67.                                 {
  68.                                         switch(_column_type[i])
  69.                                         {
  70.                                                 case ORACLE_VARCHAR2:
  71.                                                 case ORACLE_VARCHAR:
  72.                                                 case ORACLE_LONG:
  73.                                                         record_buffer.append(convertVARCHAR(_block_buf,pos,row_length));
  74.                                                         break;
  75.                                                 case ORACLE_CHAR:
  76.                                                         record_buffer.append(convertCHAR(_block_buf,pos,row_length));
  77.                                                         break;
  78.                                                 case ORACLE_NUMBER:
  79.                                                         record_buffer.append(convertNUMBER(_block_buf,pos,row_length));
  80.                                                         break;
  81.                                                 case ORACLE_DATE:
  82.                                                         record_buffer.append(convertDATE(_block_buf,pos,row_length));
  83.                                                         break;
  84.                                                 default:
  85.                                                         record_buffer.append(convertRAW(_block_buf,pos,row_length));
  86.                                                         break;
  87.                                         }
  88.                                 }
  89.                                 pos = pos + row_length;
  90.                         }
  91.                 }
  92.                 if ((ROW_LAST_PIECE & _block_buf[row_offset]) == ROW_LAST_PIECE)
  93.                         _output_file.println(record_buffer.toString());
  94.                 else
  95.                 {
  96.                         _output_file.print(record_buffer.toString());
  97.                 }
  98.         }
复制代码

使用道具 举报

回复
论坛徽章:
2
授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34
20#
发表于 2005-1-17 09:19 | 只看该作者
number 如果只有一个字符组成 大于0x80表示正无穷 小于0x80 表示负无穷
如果是我写这个程序我可能会考虑UTL_RAW.CAST_TO_NUMBER Function

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表