我给你程序,你结合BDE HELP用。
在DELPHI 3 中为DBF数据库增加Undel,Pack等功能
在用Delphi 3 开发基于Dbf 数据库时,若用Ttable元件的Delete 方法删除
一条记录,同时CachedUpdates为True (或CachedUpdates为False,但调用了
ApplyUpdates方法),则Delphi 在该条记录的物理位置的首部用“*”打上
标记(正如用Foxpro或Dbase的Del命令一样)。
在Delphi 中对各种数据库(Paradox,Dbase 等)的底层操作均是通过数据库
引擎(BDE)进行的。对于Dbase数据库,缺省情况下,BDE将标有删除标记“
*”的记录过滤掉,不提供给上层应用程序,因此使用Delphi中Data Access
页上的元件或用DataBase DeskTop均无法对这些记录进行显示和操作,因而
无法象Foxpro 那样在必要时用Undel恢复删除或用Pack 进行彻底地物理删
除。日积月累,这类记录越来越多,占用了大量的磁盘空间,降低了操作时
间,降低了安全性。因此这就要求Delphi 能提供显示已被打有“*”标记的
记录的方法(DispDeleted ),能够恢复误删除方法(Undel ),以及物理
删除有“*”标记记录的方法(PackTable)。
既然有“*”标记的记录是在数据库引擎BDE中被过滤掉的,那么也只有通过
对BDE编程,使BDE 不过滤有“*”记录,从而使用Delphi中Data Access 页
上的元件或用DataBase DeskTop能对这些记录进行显示和操作。在Borland公
司提供的BDE API 接口数据结构中有一参数 curSOFTDELETEON,当它值为
True时,则BDE不过滤有“*”记录,当它为False时,则过滤。而BDE缺省时
curSOFTDELETEON为False。因此当我们需要显示和操作有“*”记录时,我们
可以通过编程将curSOFTDELETEON设为True,当我们不需要显示和操作有“*
”记录时,我们可以将curSOFTDELETEON设为False,值得注意的是,由于“*
”不是数据库的一个“Field",因此在允许显示有“*”记录时,Delphi并不
将“*”也也显示出来,这就让使用者难以区别该条记录是否是有“*”标记
。同样,BDE的API接口中也有一个变量bDeleteFlag,当bDeleteFlag为True
时,则此记录是有J“*”标记的,反之则没有。因此当需要时,我们可以对
BDE编程,取出该变量来进行判断。关于如何对BDE进行编程,请读者参考相
关资料,本文仅针对以上几个问题给出源程序和例子,以供读者参考。
// 判断Atable 中当前记录是否已被删除, 若返回值为True 则已被删除,
否则未被删除
Function GetDelFlag(Atable: Ttable):Boolean;
var
CP: CurProps;
RP: RecProps;
begin
with Atable do begin
UpdateCursorPos; // 同步 BDE 和 Delphi
Check(DbiGetCursorProps(Handle, CP));
// 确认是Dbase 表!且已置软删除
if CP.szTableType<>szDBASE then
raise EDatabaseError.Create('Not is DBASE DBF!');
if CP.bDeletedOn = False then
raise EDatabaseError.Create('Soft deletes is not on');
// 取出删除标记
Check(DbiGetRecord(Handle, dbiNOLOCK, nil, @RP));
GetDelFlag := RP.bDeleteFlag;
end;
end;
// 设置软删除标记.
// 若使SofeDelete=True 则使BDE 不过滤有“*”标记记录,否则,过滤
procedure SetSofDelete(Table: Ttable; SoftDelete: Boolean);
var
rslt: DBIResult;
Props: CURProps;
begin
Check(DbiGetCursorProps(Table.Handle, Props));
// 确认是Dbase 表
if StrIComp(Props.szTableType, szDBASE) <> 0 then
raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);
// 确认能设置软删除
rslt := DbiValidateProp(hDBIObj(Table.Handle), curSOFTDELETEON,SoftDelete);
if rslt = DBIERR_NONE then
// 设置软删除
Check(DbiSetProp(hDBIObj(Table.Handle), curSOFTDELETEON, Longint(SoftDelete)))
else
raise EDBEngineError.Create(rslt);
end;
// 允许有“*”标记记录显示
procedure DispDeleted(Table: Ttable);
Begin
SetSofDelete(Table,True );
End;
// 不允许有“*”标记记录显示
procedure UndispDeleted(Table: Ttable);
Begin
SetSofDelete(Table,False );
End;
// 恢复删除
procedure Undel(dBASETbl: Ttable);
var
Cprops: CurProps;
begin
Check(DbiGetCursorProps(dBASETbl.Handle, Cprops));
// 确认是Dbase 表,且软删除已设置为True;
if StrIComp(Cprops.szTableType, szDBASE) <> 0 then
raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);
if Cprops.bDeletedOn = False then
raise EDatabaseError.Create('Soft deletes is not on');
Check(DbiUndeleteRecord(dBASETbl.Handle));
end;
procedure TForm1.Button1Click(Sender: Tobject);
begin
Table1.Active:=True;
DispDeleted(Table1);
end;
procedure TForm1.Button3Click(Sender: Tobject);
begin
Undel(Table1);
end;
procedure TForm1.Button4Click(Sender: Tobject);
begin
GetDelFlag(Table1);
end;
end.