在delphi中队坏库进行备份,会失败,但是失败后关闭TIBBackupService,依然无法断开与数据库文件的联系,致使无法对数据库进行修复工作,请问是什么原因,该如何解决?

解决方案 »

  1.   

    很有可能是進程還在執行中,認真一下代碼(提供一份幫助裡面的demo代碼,供參考)This   example   shows   a   component   that   backs   up   a   database   with   the   click   of   a   button.     The   second   example   shows   how   to   back   up   a   database   to   multiple   files. procedure   TForm1.Button1Click(Sender:   TObject); 
    begin 
      with   IBBackupService1   do 
        begin 
            ServerName   :=   'Poulet '; 
            LoginPrompt   :=   False; 
            Params.Add( 'user_name=sysdba '); 
            Params.Add( 'password=masterkey '); 
            Active   :=   True; 
            try 
                Verbose   :=   True; 
                Options   :=   [NonTransportable,   IgnoreLimbo]; 
                DatabaseName   :=   'c:\interbase\examples\database\employee.gdb '; 
                BackupFile.Add( 'c:\temp\employee1.gbk ');             ServiceStart; 
                While   not   Eof   do 
                    Memo1.Lines.Add(GetNextLine); 
            finally 
                Active   :=   False; 
            end; 
        end; end; To   back   up   a   database   to   multiple   files: procedure   TForm1.Button2Click(Sender:   TObject); 
    begin 
        with   IBBackupService1   do 
        begin 
            ServerName   :=   'Poulet '; 
            LoginPrompt   :=   False; 
            Params.Add( 'user_name=sysdba '); 
            Params.Add( 'password=masterkey '); 
            Active   :=   True; 
            try 
                Verbose   :=   True; 
                Options   :=   [MetadataOnly,   NoGarbageCollection]; 
                DatabaseName   :=   'c:\interbase\examples\database\employee.gdb '; 
                BackupFile.Add( 'c:\temp\e1.gbk   =   2048 '); 
                BackupFile.Add( 'c:\temp\e2.gbk '   =   4096); 
                BackupFile.Add( 'c:\temp\e3.gbk ');   ServiceStart; 
                While   not   Eof   do 
                    Memo1.Lines.Add(GetNextLine); 
            finally 
                Active   :=   False; 
            end; 
        end; 
    end;
      

  2.   

    用代碼備份試試看:HYUANDatebaseOk(DBname   ,SoureName   :   String);   
    begin   
          with   SqlCommand   do   
          begin   
              CommandText:='use   Master';//   
              Execute;   
              ClearMSSQLUser(DBname);   
              CommandText:='execute   sp_helpdevice';//系統存儲過程   
              Execute;   
              CommandText:='Restore   database   '+DBname+'     From   disk='''+SoureName+'''   with   replace';   
              Execute;   
          end;   
    end;//DBname   備份庫名稱     //SoureName   那個盤   
        
    Procedure   BakUpdatebameOk(BkDBname,MDFileStr   :   String);   
    begin   
          with   SqlCommand   do   
          begin   
              CommandText:='use   Master';   
              Execute;   
              CommandText:='execute   sp_helpdevice';//系統存儲過程   
              Execute;   
              CommandText:='backup   database   '+BkDBname+'   to   disk='''+MDFileStr+'''   with   init';   
              Execute;   
              CommandText:='Use   '+BkDBname;   
              Execute;   
          end;   
    end;   
    procedure   ClearMSSQLUser(DBname   :   String);   
    var   
          SelectQuery   :   TAdoQuery;   
          ClearProUser   :   TAdoQuery;   
    begin   
          try   
              SelectQuery   :=TAdoQuery.Create(nil);   
              ClearProUser:=TAdoQuery.Create(nil);   
              SelectQuery.Connection   :=SqlConnection;   
              ClearProUser.Connection:=SqlConnection;   
              SelectQuery.SQL.Clear;   
              ClearProUser.SQL.Clear;   
              SelectQuery.SQL.Add('select   *   from   dbo.sysobjects   where   '+   
                                                      'id   =   object_id(N''[dbo].[p_killspid]'')   and   OBJECTPROPERTY(id,   N''IsProcedure'')   =   1');   
              SelectQuery.Open;   
              if   SelectQuery.Eof   then   
              begin   
                  SqlCommand.CommandText:='create   proc   p_killspid   '   +   
                                                                    '@dbname   sysname                 '   +   
                                                                    'as     '+   
                                                                    'declare   @s   nvarchar(1000)   '   +   
                                                                    'declare   tb   cursor   local   for   '   +   
                                                                    'select   s=''kill   ''+cast(spid   as   varchar)   '+   
                                                                    'from   master..sysprocesses   '+   
                                                                    'where   dbid=db_id(@dbname)   '+   
                                                                    'open   tb   '+   
                                                                    'fetch   next   from   tb   into   @s     '+   
                                                                    'while   @@fetch_status=0       '+   
                                                                    'begin     '+   
                                                                    '     exec(@s)     '+   
                                                                    '     fetch   next   from   tb   into   @s     '+   
                                                                    'end   '+   
                                                                    'close   tb   '+   
                                                                    'deallocate   tb';   
                  SqlCommand.Execute;   
              end;   
              SqlCommand.CommandText:='exec   p_killspid     '''+DBname+'''';   
              SqlCommand.Execute;   
          finally   
              freeandnil(SelectQuery);   
              freeandnil(ClearProUser);   
          end;   
    end;
      

  3.   

    在finally里关闭成功了?
    会不会是InterBase自身的原因
      

  4.   

    誰說控件關了,進程就斷開了?它有可能佔用著database呢,對不對??
    我一般的做法就是直接用代碼,不用控件;你帶加上一個進度條來顯示備份進度實在找不到原因,你就追蹤一下代碼,設置一個斷點看一下,是不是finally時確實close成功了...
      

  5.   

    這是我系統現在使用的備份和還原
    procedure Tsys_datamodule.DataBaseBack;
    var
      FileName:string;
      ADOQ:TADOQuery;
    begin
      ADOQ:=TADOQuery.Create(nil);
      ADOQ.Connection:=sys_datamodule.con1;
      if MessageDlg('你確定要備份數據庫嗎?',mtInformation,[mbYes,mbNo],0)=idyes then
      begin
        try
          if SaveDialog1.Execute then
          begin
            FileName:=SaveDialog1.FileName;
            if (Copy(FileName,Length(FileName)-3,4)<>'.BAK') or (Copy(FileName,Length(FileName)-3,4)<>'.bak') then
              FileName:=FileName+'.BAK';
            ADOQ.SQL.Text:='Use Master Backup Database MES to Disk='''+ FileName+''' Use MES';
            ADOQ.ExecSQL;
            MessageDlg('數據庫備份成功!',mtInformation,[mbOK],0);
          end;
        except
          MessageDlg('數據庫備份失敗!',mtInformation,[mbOK],0);
          Exit;
        end;
      end;
    end;procedure Tsys_datamodule.RestoreBaseBack;
    var
      StrFile:string;
      ADOQ:TADOQuery;
    begin
      ADOQ:=TADOQuery.Create(nil);
      ADOQ.Connection:=sys_datamodule.con1;
      if MessageDlg('你確定要還原數據庫嗎?',mtInformation,[mbYes,mbNo],0)=idyes then
      begin
        try
          if OpenDialog1.Execute then
          begin
            StrFile:=OpenDialog1.FileName;
            ADOQ.SQL.Text:='Use Master Restore Database MES From Disk='''+ StrFile+''' Use MES';
            ADOQ.ExecSQL;
            MessageDlg('數據庫還原成功!',mtInformation,[mbOK],0);
          end;
        except
          MessageDlg('數據庫還原失敗!',mtInformation,[mbOK],0);
          Exit;
        end;
      end;
    end;
      

  6.   

    单步执行走到那里,控件active是false了,肯定是关了,但是就是数据库文件依然被占用了
      

  7.   

    動動手嘛,你試試不就知道嗎?關了就被佔用,沒有執行完任務啊奇怪麼,肯定是進程HANDLE
      

  8.   

    现在我是想办法要解决进程无法关闭的问题,每次采用重启数据库服务的方式觉得不合理
    它本身的备份操作没有任何错误,firebird数据库已经有了很好的备份方式,我觉得单纯的copy不是很理想