热情软件屋

 

如何永久地删除数据库表中带有删除标记的记录


编号:QA000649
建立日期: 1999年3月16日 最后修改日期:1999年3月16日
所属类别:

陈永福:
    我用Delphi 3进行数据库编程时,希望能有一种简单且直接的方法永久地删除数据库表中带有删除标记的记录,就如使用Foxpro或Dbase中的PACK命令那样,而不希望要通过中间数据库过渡的形式,如 TABLE1.BatchMove方法),以节省宝贵的空间。

回答:

    对于各种数据库类型,只有xBase和Paradox采用这种删除方式,为了释放空间你必须借助BDE API中。关于BDE API的详细介绍参见Delphi的BDE API Help。对于Paradox,使用DBIDoRestructure语句,而对于xBase采用DBIPackTable语句。下面是一个永久地删除Paradox数据库表中带有删除标记的记录的例子:
    procedure TForm1.PackParadoxTable( TableName, Alias : String);
    {TableName should be with extension - .DB}
    var
    hDB :hDBIDb;
    hCursor :hDBICur;
    DBResult :DBIResult;
    PdoxStruct :CRTblDesc;
    szTableName : PChar;
    szAlias : PChar;
    PathLength : Integer;
    ErrMsg : String;
    begin
     PathLength := 120;
     GetMem(szTableName, PathLength);
     GetMem(szAlias, 20);
     StrPCopy(szTableName, TableName);
     StrPCopy(szAlias, Alias);
     Try
     {First you need to initialize the Borland Database Engine}
     DBResult := DBIInit(nil);
     if DBResult <> DBIERR_NONE then begin
     MessageDlg('Error Initializing BDE',mtError,[mbOk],0);
     DBIExit;
     Exit;
     end;
     {If the Initializing was OK then Open the Database}
     DBResult := DBIOpenDatabase(szAlias,'STANDARD',DBIREADONLY,DBIOPENSHARED,'',0,nil,nil,hDB);
     if DBResult <> DBIERR_NONE then begin
     case DBResult of
     DBIERR_INVALIDFILENAME : ErrMsg := 'Invalid FileName';
     DBIERR_NOSUCHFILE : ErrMsg := 'No Such File';
     DBIERR_TABLEREADONLY : ErrMsg := 'Table is READ ONLY';
     DBIERR_NOTSUFFTABLERIGHTS : ErrMsg := 'Not Sufficent Table Rights';
     DBIERR_INVALIDHNDL : ErrMsg := 'Invalid Handle';
     DBIERR_LOCKED : ErrMsg := 'Table Locked';
     DBIERR_DIRBUSY : ErrMsg := 'Directory Busy';
     else
     ErrMsg := 'Unknown Error';
     end;
     MessageDlg(ErrMsg,mtError,[mbOk],0);
     DBIExit;
     Exit;
     end;
     {Opening the table returns a Handle to the table's cursor. So now Open the Table}
     DBResult := DBIOpenTable(hDB,szTableName,'','','',0,DBIREADWRITE,DBIOPENEXCL,
     xltNONE,False,nil,hCursor);
     if DBResult <> DBIERR_NONE then begin
     case DBResult of
     DBIERR_INVALIDFILENAME : ErrMsg := 'Invalid FileName';
     DBIERR_NOSUCHFILE : ErrMsg := 'No Such File';
     DBIERR_TABLEREADONLY : ErrMsg := 'Table is READ ONLY';
     DBIERR_NOTSUFFTABLERIGHTS : ErrMsg := 'Not Sufficent Table Rights';
     DBIERR_INVALIDHNDL : ErrMsg := 'Invalid Handle';
     DBIERR_LOCKED : ErrMsg := 'Table Locked';
     DBIERR_DIRBUSY : ErrMsg := 'Directory Busy';
     DBIERR_OPENTBLLIMIT : ErrMsg := 'Open Tables Limit';
     DBIERR_INVALIDINDEXNAME : ErrMsg := 'Invalid Index Name';
     DBIERR_NOSUCHTABLE : ErrMsg := 'No Such Table';
     else
     ErrMsg := 'Unknown Error';
     end;
     MessageDlg(ErrMsg,mtError,[mbOk],0);
     DBICloseDatabase(hDB);
     DBIExit;
     Exit;
     end;
     Try
     DBICloseCursor(hCursor); {Table Cursor needs to be closed}
     {Initialize the record Structure CRTblDesc}
     FillChar(PdoxStruct, SizeOf(CRTblDesc),0);
     StrPCopy(PdoxStruct.szTblName, TableName);
     PdoxStruct.bPack := True;
     DBResult := DBIDoRestructure(hDB,1,@PdoxStruct,nil,nil,nil,False);
     if DBResult <> DBIERR_NONE then
     MessageDlg('Failed to Pack Table',mtError,[mbOk],0);
     Finally
     DBICloseCursor(hCursor);
     DBICloseDatabase(hDB);
     DBIExit;
     end;
     Finally
     FreeMem(szTableName, PathLength);
     FreeMem(szAlias, 20);
     end;
    end;

此问题由李海回答。

 
把这个问题推荐给朋友
   
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio