Delphi中删除DBF数据只做了删除标志,怎样才能彻底删除

解决方案 »

  1.   

    http://www.enet.com.cn/eschool/inforcenter/A20040320296088.html1. 对于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(          '以独占方式打开数据库时,出现错误---重试否?',          '数据库错误',          MB_OKCANCEL + MB_DEFBUTTON1) < > IDOK then          Exit;         end;         until False;        try         {Check()用于校正和报告DBI底层错误;DbiGetCursorProps()用于取表光标属性}         Check(DbiGetCursorProps(FTable.Handle, Props));// 获得表的属性已得到表的类型         {如果是Paradox 表, 必须调用 DbiDoRestructure,重建数据库结构}          if (Props.szTableType = szPARADOX) then           begin            FillChar(TableDesc, sizeof(TableDesc), 0);            {从数据表光标获取数据库句柄}           Check(DbiGetObjFromObj(hDBIObj(FTable.Handle), objDATABASE, hDBIObj(hDb)));           {设置表的描述结构的Name/Type/bPack属性}            StrPCopy(TableDesc.szTblName, FTable.TableName);            StrPCopy(TableDesc.szTblType, Props.szTableType);            TableDesc.bPack := True;            {关闭表并调用api} 
                FTable.Close;             Application.ProcessMessages; 
                Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, False)); 
                Application.ProcessMessages; 
                FTable.Open; 
                end 
               { 如果是 dBASE 表, 只需要调用DbiPackTable...} 
              else 
               if (Props.szTableType = szDBASE) then 
                begin 
                 Application.ProcessMessages; 
                 Check(DbiPackTable(FTable.DBHandle, FTable.Handle, nil, szDBASE, True)); 
                 Application.ProcessMessages; 
                end 
              {不是dBase和Paradox表} 
              else 
               raise EDatabaseError.Create('数据库必须是 Paradox 或者 dBASE 类型,才能进行物理删除操作!!'); 
               finally 
               FTable.Active := False; 
               FTable.Exclusive := False; 
               FTable.Active := True; 
              end; 
             end;   procedure TfrmPack.BitBtndBaseClick(Sender: TObject); 
       begin 
        if OpenPictureDlg.Execute then 
         DBImage1.Picture.LoadFromFile(OpenPictureDlg.FileName); 
        end;   procedure TfrmPack.BitBtnParadoxClick(Sender: TObject); 
       begin 
        if OpenPictureDlg.Execute then 
         DBImage2.Picture.LoadFromFile(OpenPictureDlg.FileName); 
       end;   procedure TfrmPack.BitBtnPackdBASEClick(Sender: TObject); 
       begin 
        PackTable(tbldBASE);//物理删除dDBSE库 
       end;   procedure TfrmPack.BitBtnPackParadoxClick(Sender: TObject); 
       begin 
        PackTable(tblParadox);//物理删除Paradox库 
      end;