Delphi目前已经是国内常见的数据库编程工具,它在各方面表现不错,在支持大型多层数据库结构的同时也完全支持本地数据库。对于本地数据库中Delphi对FoxPro的支持也不错,我曾经对VB、FoxPro、Delphi的数据库操作速度进行比较,发现除了启动速度较慢外,其它各项Delphi均排在首位。而且Delphi几乎支持所有原先FoxPro所拥有的功能,对于有一定编程经验的人来说,Delphi成了编写数据库软件的一把利器,因而Delphi迅速流行起来,Delphi在我国也占有一席之地。
但是我在使用Delphi编程的过程中发现它也有不如人意的地方,特别是在本地数据库dBase和Paradox方面,它居然不支持十分有用的Pack和Undelete功能。对于数据库来说,因为是一个顺序存储文件,在删除部分记录时一般采用了软删除技术,也就是说将要删除的记录标记已删除的标记,但并不立即从物理上删除这些记录(删除后库文件大小不变)。
这样做可以避免仅仅删除一条记录就要将整个数据库重新写入存储器,提高了读写的效率。但是如果数据库长期不对已经被标记为删除的记录进行整理和真实删除,数据库就会越来越大,其中无用的数据所占的比率越来越大,使得数据库的读写效率迅速下降,而且造成查询速度的减慢。特别是在编写人事管理数据库应用软件时,库内要保存大量的图形文件(人员的照片),而这些数据还时常需要添加和删除,没用的数据不能"Pack"将占用巨大的硬盘空间,而且还将降低系统的运行速度。
这是编写数据库软件的人必须考虑的一个问题。经过再三查找,我找到一些资料,解决了如何对数据库进行pack,下面是其中的核心程序的一个例子,在看例子之前,我先做一些说明:
1. 对于dBase和Paradox库,其Pack原理是不同的:如果是Paradox 表, 必须调用 DbiDoRestructure,重建数据库结构;如果是 dBASE 表, 只需要调用DbiPackTable。
2. 在做Pack删除时,必须以独占方式打开数据库时。具体请参考一下的例子。
(为了节省篇幅,例子中只给出关键性的程序段)
implementation
uses BDE;//做PACK必须引用次单元里的函数
{$R *.DFM}
procedure TfrmPack.FormCreate(Sender: TObject);
var
DBName:String;
begin
DBName:=ExtractFilePath(Application.ExeName);//得到数据库的位置
{设置Table}
tblDBASE.DatabaseName:=DBName;
tblParadox.DatabaseName:=DBName;
tblDBASE.TableName:='dbsTest.dbf';
tblParadox.TableName:='pdxTest.db';
tblDBASE.Active:=True;
tblParadox.Active:=True;
end;
{物理删除数据库记录Pack a Paradox or dBASE table}
// The table must be opened execlusively before calling this procedure...
procedure TFrmPack.PackTable(FTable: TTable);
var
Props: CURProps;
hDb: hDBIDb;
TableDesc: CRTblDesc;
begin
FTable.Active := False;
{当数据库打开失败时,这个循环语句能够让用户重试}
repeat
try
FTable.Exclusive := True;
FTable.Active := True;
{如果正常打开数据库,则退出循环}
Break;
except
on EDatabaseError do
if Application.MessageBox(
'以独占方式打开数据库时,出现错误---重试否?',
上一篇:浅述Delphi下的OpenGL图形开发
下一篇:第四章 文本编辑器的设计(一)
|