`

为Delphi提供Pack和Undelete功能

阅读更多

4.为Delphi提供Pack和Undelete功能
weiwu

本文针对Delphi3和Delphi4,对于C++Builder同样也适用,在数据库引擎BDE4.0、4.5、5.0中经过测试。

Delphi目前已经是国内常见的数据库编程工具,它在各方面表现不错,在支持大型多层数据库结构的同时也完全支持本地数据库的支持。对于本地数据库中Delphi对FoxPro2.5b的支持也不错,我曾经对VB、FoxPro2.5b、Delphi的数据库操作速度进行比较,发现除了启动速度较慢外,其它各项Delphi均排在首位。而且Delphi几乎支持所有原先FoxPro所拥有的功能,对于有一定编程经验的人来说,Delphi成了编写数据库软件的一把利器,因而Delphi迅速流行起来,我几年前甚至利用Delphi 1.0和汇编配合制作了工业控制系统的实时前后台软件。

但是在我长期使用Delphi编程的过程中发现它也有不如人意的地方,特别是在本地数据库FoxPro方面,它居然不支持十分有用的Pack和Undelete功能。对于数据库来说,因为是一个顺序存储文件,在删除部分记录是一般采用了软删除技术,也就是说将要删除的记录标记已删除的标记,但并不立即从物理上删除这些记录。这样做可以避免仅仅删除一条记录就要将整个数据库重新写入存储器,提高了读写的效率。但是如果数据库长期不对已经被标记为删除的记录进行整理和真实删除,数据库就会越来越大,其中无用的数据所占的比率越来越大,使得数据库的读写效率迅速下降,而且造成查询速度的减慢。在编写FoxPro数据库时有个规律,如果数据进出数据库频繁,也就是说不断删除旧的数据,加入新的数据的情况下每次在关闭数据库的时候或打开数据库的时候先做一次Pack,对数据库进行整理,将软删除的记录真正从数据库中删除。但是在Delphi的各个版本中数据库控件均未提供Pack的功能,这使得用Delphi编写的数据库软件如果使用本地数据库的形式,数据库的大小增长很快,即使删除了大量记录,数据库的大小没有任何改变。以前我的做法是在使用这类数据库软件一段时间后利用FoxPro打开数据库进行Pack,但是这样做要求客户端拥有FoxPro,而且经常这么做也很繁。于是我开始查找有关资料,为什么Delphi无法使用pack功能?

经过再三查找,我找到一些资料,说明如何对数据库进行pack了,在将其改编后在Delphi中使用通过。下面是其中的核心程序。

BDE API Call:

DBIResult DBIFN DbiPackTable (hDb, hCursor, pszTableName, [

pszDriverType], bRegenIdxs);

在数据库引擎的底层函数调用中,我找到了这个函数,这个函数据说可以对FoxPro的数据库进行Pack,其中hDb是数据库的句柄,可以由Table.Handle获得;hCursor是数据表(Table)关联的游标,如果为NULL则数据表依赖于pszTableName和pszDriverType这两个传输决定数据库的来源;bRegenIdxs决定是否关联外接的索引文件尤其是MDX多索引文件。

具体的操作函数如下:

procedure PackTable(Table: TTable);

var

Props: CURProps;

hDb: hDBIDb;

begin

if not Table.Active then

raise EDatabaseError.Create('Table必需已经打开');

if not Table.Exclusive then

raise EDatabaseError.Create('Table必需以独占方式打开');

Check(DbiGetCursorProps(Table.Handle, Props));

if (Props.szTableType = szDBASE) then

Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, True))

else

raise EDatabaseError.Create('Table必需是dBASE或FoxPro类型');

Table.Open;

end;

特别对这段源码说明一下,这段源码部分改编自C,已经在上面提到过的环境中测试通过,需要注意的是,数据表必需以独占方式打开,简单的说,就是在设计时将数据表关闭(属性Active=False),在运行时才打开数据表(form_onCreate时Table.Open),这样才能保证数据表在独占方式下被打开。DbiGetCursorProps()是一个读取数据表的属性的底层函数调用,返回了大部分通用的数据表属性。Check()函数可以简单的处理数据库的出错提示和异常处理,如果出现函数调用错误会自动显示出错信息。

说了pack那么与之对应的Undelete也就更要解释了,同样我找到了将软删除的数据恢复的函数,不过这个函数隐藏的更深,连C代码都没有,所以以下的代码完全由我自己摸索出来,仅在上面说到的环境中测试通过。

首先介绍一下相应的底层函数调用:

DBIResult DBIFN DbiUndeleteRecord (hCursor);

这个函数仅有的参数就是关联的数据表的游标,您可以在BDE.int的文件中找到它的声明,但是具体的使用说明含糊不清,到底是恢复当前被删记录还是将数据表内所有被软删除的记录全部恢复?由于缺少相应的代码分析,我参照FoxPro的经验进行了多次实验,在十几种方案的对比下得出了结论,这条函数调用仅仅恢复当前的被软删除的记录。因此必需首先将数据表的游标移动到被删除的记录上,然后调用这条函数,才会有所反应。要知道在默认的情况下,数据库控件是不会将游标移动到被删除的记录上的,所以必需首先将数据表的读写属性修改,打开软删除的属性,使得遍历数据表时可以访问到被标记为删除的记录。下面是一段实现将数据表中所有被软删除的记录恢复的源代码。其它形式的反删除可以参照这段代码。

procedure Ttablepro.undelete;

var

CProps: CurProps;

rslt: DBIResult;

bm:TBookmark;

rp:pRECProps;

begin

Check(DbiGetCursorProps(self.Handle, CProps));//取得数据表的属性

if (StrIComp(CProps.szTableType, szDBASE) <> 0) then//如果不是Dbase或Foxpro则退出

raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);

rslt:=DbiValidateProp(hDBIObj(self.Handle), curSOFTDELETEON, True);

//可否设置软删除?

if (rslt = DBIERR_NONE) then

Check(DbiSetProp(hDBIObj(self.Handle), curSOFTDELETEON, Longint(true)));

//设置为可以软删除

Check(DbiGetCursorProps(self.Handle, CProps));

//更新数据表的属性

if (CProps.bDeletedOn = False) then

raise EDatabaseError.Create('软删除没有设置!');

//取得当前的记录位置

bm:=self.GetBookmark;

//将游标移动到第一个记录以前!Not Table.First!

Check(DbiSetTobegin(self.handle));

//不断移动,直到到数据表的最后记录

while (DBIGETNEXTRECORD(self.handle,dbinolock,nil,nil)=DBIERR_NONE) do

begin

//请关闭Delphi的异常响应,以便执行下面的语句!

try

check(DbiUndeleteRecord(self.Handle));

except

//Do somthing here !

end;

end;

//取回原先记录的位置,重新定位

self.GotoBookmark(bm);

self.FreeBookmark(bm);

self.Refresh;

end;

(注:如果可以,请在刊登时删去“Self.refresh”一行,对于原理的介绍无需此行,仅在我的控件的属性中需要,以上代码来自我制作的Delphi控件TTablePro)

分享到:
评论

相关推荐

    专业数据恢复软件Undelete2009,为用户提供实时数据保护和即时数据恢复功能。

    ● 通过Office版本保护功能恢复旧版本的Word、Excel和PowerPoint文件。 ● 支持64位操作系统,包括Windows Vista和Windows Server 2008。 ● 磁盘搜索技术(Search Disk):搜索并恢复被删除的文件。 ● 紧急恢复技术...

    Undelete360数据恢复软件 v2.1.6.26 免费版.rar

    Undelete360 是款俄罗斯出品的绿色免费快速小巧的数据恢复软件,比FinalData好用多了,至少速度快 N 倍,而且是安全免费的软件哦!...它是完全免费为你使用和享受。 缺点:对视频类文件支持有限,仅支持.swf文件。

    Undelete

    绿色恢复软件 用来恢复已经删除的文件

    xfs_undelete-master.zip

    xfs_undelete-master

    undelete 360 2.1.6.25

    Undelete 360是一款简单易用功能强大的数据恢复软件 1、可以恢复本地磁盘、数码相机、软盘、U盘的数据;  2、恢复意外删除的文件和文件夹、恢复因病毒引起的文件丢失;  3、恢复因删除文件时因文件太大没有以过...

    undelete_plus

    Undelete PLUS是一个免费的带有中文界面的数据恢复软件,主要用于恢复误删除的文件。Undelete PLUS软件体积小,可以快捷、有效地恢复误删除的文件,Undelete PLUS提供了绿色版和安装版,绿色版可以放在U盘上使用。

    Active undelete 8反删除恢复文件好工具

    Active undelete 8反删除恢复文件好工具,支持多种方式进行扫描和恢复

    Glary Undelete v5.0.1.19.zip

    Glary Undelete可以救硬碟的档案,连随身碟、记忆卡、外接磁碟都能救,而且支援FAT、NTFS等档案系统 Glary Undelete截图

    undelete_plusun[删除恢复工具]

    undelete_plusun[删除恢复工具]

    Active@ UNDELETE Enterprise Edition v7.1.050

    Active@ Undelete 是一个功能强大的数据恢复软件,程序可以帮助你快速的恢复被因误删除,格式化磁盘而丢失的文件和数据,本软件是企业完整版,注册信息: Name:Francis Larson SN:0TCKYR-1HDKD0-XQX2GQ-DCUZVC-H2H8FE

    误删数据恢复软件:Undelete 360

    Undelete 360 采用快速有效的算法,可以快速搜索并恢复因计算机故障、误操作意外删除、计算机病毒等原因而意外丢失的文件和数据!...更另人惊喜的是undelete 360体积小巧 ,完全免费,没有任何广告和功能限制!

    Undelete_Beta

    恢复手机误删的资料,图片,视频,音乐等。Undelete_Beta_

    Smart Undelete v3.12

    smartundelete是一款强大的数据恢复软件,能有效的找回已被删除的文件,巧妙的恢复被删除的文件,甚至是那些你认为无法挽救的损失

    Undelete Plus

    恢复误删除文件 Undelete Plus可以快捷而有效地恢复误删除的文件,包括从回收站中清空,DOS窗口中删除,网络驱动器,Windows Explorer的Shift快捷键删除的文件都可以帮你找回,支持FAT12/FAT16/FAT32/ NTFS/...

    恢复误删除的文件 Undelete Plus V3.02 Build 406

    Undelete Plus可以快捷而有效地恢复误删除的文件,包括从回收站中清空,DOS窗口中删除,网络驱动器,Windows Explorer的Shift快捷键删除的文件都可以帮你找回.支持FAT12/FAT16/FAT32/NTFS/NTFS5文件格式.

    undelete-360

    恢复文件,误操作删除了文件需要恢复。 undelete-360

    强大的 FAT 和 NTFS 数据恢复工具 R-Undelete 6.5 Build 170927 中文免费版.zip

    与之前的版本相比,R-Undelete 4.x 为数据恢复新手提供了增强型向导风格界面和从受损及已删除分区中恢复文件的选项,除了 RAID、十六进制编辑和网络支持等一些专用的数据恢复功能,这也使 R-Undelete 成为了优秀的 R...

    硬盘恢复工具Undelete 360

    摘要:Undelete 360 Professional误删恢复专家,是给你的电脑开出的一味后悔药,它能帮助你把已经删除且从回收站清空的文件重新找回来. 是个简单易操作的数据恢复软件,全中文界面,很容易上手。 操作如图,误删恢复...

    undelete工具

    对于光盘没有恢复能力,但是速度很快!好像有中文版本,需要自己调。建议使用文件夹视图。此外:完全免费(非破解)和国内的360无任何关系,请安心下载

Global site tag (gtag.js) - Google Analytics