赛迪网 > IT技术 数据库 > 精彩更新
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

Paradox的数据表损坏后如何来修复

发布时间:2006.11.02 05:04     来源:CSDN    作者:matq2008

Paradox数据库是一种桌面型数据库,具有有效性检查、参考完整性、口令保护、字段类型丰富等特点。但是在实际使用过程中,当数据库引擎出现问题时,由于数据没有全部写入数据库中,可能造成数据库损坏。本文介绍Paradox数据库的数据表即DB文件损坏时的修复办法。

DB文件格式

Paradox数据表的损坏可分为两种情况:一是数据表表头损坏,数据根本读不出来;二是数据块链表出现问题,只能看见部分记录。无论是上述哪种情况,只要DB文件中的记录仍然存在(本文称这种损坏为逻辑损坏),就有可能恢复数据。

要恢复数据,必须了解DB文件的格式。DB文件保存着一个数据表的数据记录,DB文件里的第一个块是表头(块),表头后面跟着数据块。DB文件的逻辑结构如下图所示:

其中表头(表头中部分字段的描述如表1所示)包含第一个数据块、最后一个数据块和第一个自由块的块号。每个块都有编号,在表头后面的第一个块号码是1。全部块(表头除外)都有相同的大小,这意味着块号能用来计算块的偏移量:

块偏移=块长度×(块号码-1)+表头长度

数据块分块头和记录两部分,其中块头由数据块的前6个字节组成。数据块使用双向链表进行组织,链表元素(或称为节点)是块头的前4个字节,包含了下一个数据块和前一个数据块的块号。在数据块内,记录顺序存储,记录间没有空隙,数据块的块头中还包含了当前块中最后一个记录的偏移量。表2是数据块格式描述。

其中最后一个记录的偏移量和块头部的末端相关,并以块号加6计算偏移量。

分析问题

有了表的结构知识,我们就可以用它来分析数据表损坏的原因,从而找出修复数据表的方法。

当数据表逻辑损坏时,如果数据库引擎报告表索引头错误,通过分析可知多半是表头中有关块或记录的参数不匹配,比如“使用的块数”大于“总的块数”,或是记录数和块数不匹配。如果只能显示部分数据,可能是表头中“总的记录数”小于实际记录数,也可能是数据块链表错乱。

如果只是表头索引参数出了问题,我们可以通过分析表头相关信息,用16进制编辑器直接进行参数修改就可解决问题;如果是数据块链表出了问题,一般无法直接修改(比如对有成千上万条记录的数据表)。

笔者的方法是采用冗余方式计算链表,即数据块和记录都按最大数进行处理。每个数据块中记录的最大数跟数据块大小和记录长度有关,其关系为:记录数(max)=[数据块大小÷记录长度]([]表示取运算结果的整数部分);而数据块的多少又跟DB文件大小有关,其关系为:数据块数(max)=(文件大小-块头大小)÷数据块大小(这一运算结果应为整数,如果不为整数则取不小于它的最小整数)。以计算出来的两个数据修改表头索引参数,然后再根据表头参数将链表修复为顺序结构链表。到此为止,可以说基本上修复了数据表。不过,这样一来表中就可能出现重复数据或无用数据,因此还要对数据表进行排序、删除重复记录等处理,然后就可以得到一个比较完美的数据表。

编程实现

下面给出用C++ Builder编程来修改表头索引和数据块链表的主要源代码。需要注意的是,该方法不适用于有密码的数据表。

用C++ Builder 新建一个工程,在窗体上创建一个OpenDialog1组件和一个Button1组件,并将OpenDialog1的Filter属性设置为“*.DB|*.DB”,然后在Button1的OnClick事件中加入以下代码:

void   __fastcall   TForm1::Button1Click(TObject   *Sender)     
  {     
  if(OpenDialog1->Execute())     
   {     
    //变量声明     
    AnsiString   fn;     
    unsigned   char   fd[65];     
  int   rl,lhb,dbs,nr,tb;//rl为记录长度,lhb为表头块长度,dbs为数据块大小,
nr为记录数,tb为总的数据块数     
    unsigned   long   sof;     
    struct   stat   statbuf;     
    fstream   DBFile;     
    //获取待修改数据表名     
    fn=OpenDialog1->FileName;     
  //获得文件大小,以此计算数据表中最大的块数     
  int   handle;     
    handle=open(fn.c_str(),O_RDONLY);     
    fstat(handle,   &statbuf);     
    sof=statbuf.st_size;     
    close(handle);     
  //打开文件并将表头信息读取到数组fd中     
    DBFile.open(fn.c_str(),ios::in|ios::out|ios::binary);     
    DBFile.read(fd,64);     
    //计算总的块数     
    dbs=fd[5]*1024;     
    lhb=fd[2]+fd[3]*256;     
    tb=ceil((sof-lhb)/dbs);     
    //根据总块数计算总的记录数     
    rl=fd[0]+fd[1]*256;     
    nr=dbs/rl;     
    nr=nr*tb;     
    //修改总的记录数     
    fd[6]=nr%256;     
    fd[7]=nr/256;     
    fd[8]=nr/(256*256);     
    fd[9]=nr/(256*256*256);     
    //修改数据块数     
    fd[10]=fd[12]=fd[16]=fd[58]=tb%256;     
    fd[11]=fd[13]=fd[17]=fd[59]=tb/256;     
    fd[14]=1;     
    fd[15]=0;     
    //将相关信息写到文件中     
    DBFile.seekg(0,0);     
    DBFile.write(fd,64);     
    //根据表头信息修复数据块链表     
    if(tb>1)     
     for(int   i=0;i<tb;i++)     
       {     
       if(i==0)   {fd[0]=2;fd[1]=0;fd[2]=0;fd[3]=0;}     
       else   if(i==tb-1)   {fd[0]=0;fd[1]=0;fd[2]=i%256;fd[3]=i/256;}     
       else   {fd[0]=(i+2)%256;fd[1]=(i+2)/256;fd[2]=i%256;fd[3]=i/256;}     
       DBFile.seekg(lhb+dbs*i,0);     
       DBFile.write(fd,4);     
     }     
    //关闭文件     
    DBFile.close();     
    ShowMessage(“修复操作完成!”);     
   }     
  }

(T114)


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· 教您如何用蒸汽熨斗来修复划痕光盘 (05-25) · 硬盘分区坏了咋办?硬盘分区修复全攻略 (04-13)
· 谈硬盘出现物理坏道的迹象及修复技巧 (04-13) · 硬盘维修—修复被逻辑炸弹损坏硬盘 (04-13)
· 用Delphi程序维护Paradox 数据表的索引 (04-06) · 悠然自得--让WinXP自行修复系统故障 (04-05)
· 使用MHDD2.9修复硬坏道的方法 (02-14) · 重新安装系统后修复受损的FlashGet (12-30)
· IBM推数据中心软件新品 有自诊断修复功能 (12-06) · IBM推数据中心软件新品 有自诊断修复功能 (12-06)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
[政务][电信][金融][农业][制造业][中小企业]
[CIO][ERP][协同][IT管理][中间件][电子商务]
[政策][地方][专家][评估][辞典][博客][社区]
· 专题:一路畅通构想曲——让出行不再遭遇堵车
· CIO工作亲历:企业ERP选型不能忽视"选人关"
· 综述:信息化建设给中国监狱带来的各种变化
· 金融业风险管理和法规遵从有五点需考虑的因素
· 保险业CIO关注:该如何建立统一高效的CRM体系
· 调查显示:多数CIO对IT规划仍存在困惑和误解
  博客·论坛 ·曾剑秋·项立刚·Java学习·网管