我用的是SQL SERVER 2000,在程序中我是这样做的,在主窗体中点击'备份/恢复数据库'菜单,弹出'备份/恢复数据库'窗体,该窗体中有两个RadioButton控件(用于选择是进行备份操作还是恢复操作), 还有就是一个Bitbtn1按钮,caption为'备份/恢复'.在datamodule中定义有一个m_Adoconnection,是连到要备份的数据库,(名为RecData),在'备份/恢复窗体'中定义了一个other_Adoconnection,用于连接master数据库.当我在进行恢复操作时出现了这样的问题,第一次进入'备份/恢复窗体'中进行恢复操作时没问题,但在退出窗体后,再次进入'备份/恢复窗体'中进行恢复操作时就会出错,提示:数据库正在使用,无法进行排它访问.这是为什么呢,请大家指点一二.具体代码如下:
procedure TDbManageForm.btnDBManageClick(Sender: TObject);
var
  DBManageQuery:TAdoQuery;
begin
  if(BackupRdBtn.Checked )then     //备份
  begin
    SaveDialog1.FileName :='Backup'+FormatDateTime('yyyymmdd',Date);
    if(SaveDialog1.Execute )then
    begin
      Other_AdoConnection.Connected :=true;
      DBManageQuery:=TAdoQuery.Create(Self);
      DBManageQuery.Connection :=Other_AdoConnection;
      try
        with DBManageQuery do
        begin
          Close;
          SQL.Clear ;
          SQL.Add('Backup Database RecData To Disk=''' + SaveDialog1.FileName + ''' With Init');
          ExecSQL;
        end;
      except
        on e:exception do
         //
      end;
      DBManageQuery.Free ;
      Other_AdoConnection.Connected :=false;
    end;
  end
  else if(RestoreRdBtn.Checked )then          //恢复
  begin
      if(OpenDialog1.Execute )then
      begin
        DBManageQuery:=TAdoQuery.Create(Self);
        DBManageQuery.Connection :=Other_AdoConnection;
        Other_AdoConnection.Connected :=true;
        try
          with DBManageQuery do
          begin
            Close;
            SQL.Clear ;
            SQL.Add('Restore DataBase RecData From Disk=''' + OpenDialog1.FileName + '''');
            ExecSQL;
          end;
        except
          on e:exception do
          //
        end;
        DBManageQuery.Free ;
        Other_AdoConnection.Connected :=false;
      end;
    end;
end;procedure TDbManageForm.FormShow(Sender: TObject);
begin
  DataModule1.m_AdoConnection.Connected :=false;
end;procedure TDbManageForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  DataModule1.m_AdoConnection.Connected :=true;
end;

解决方案 »

  1.   

    http://blog.csdn.net/jadeseala/archive/2004/09/01/91072.aspx
    http://www.ask321.com/ask28/how196251.htm不知道有没有帮助哦
      

  2.   

    谢谢小狗,我去看看.
    不好意思,上面我弄错了,我现在发现是第一次进入'备份/恢复窗体'进行恢复操作时就会报错,提示:因为数据库正在使用,未能获得对数据库的排它访问权.这样就感觉好象是procedure TDbManageForm.FormShow(Sender: TObject);过程中的DataModule1.m_AdoConnection.Connected :=false;没有正确执行似的,不然的话,应该不会有错的呀,为什么会这样的呢
      

  3.   

    是在执行restore这句时出错的,本来第一次就出错的,是我原来弄错了以为是对的了
      

  4.   

    //备份
    procedure TForm23.Button1Click(Sender: TObject);
    begin
    if savedialog1.Execute then
    begin
      adoquery1.SQL.Text:='backup database mydatabase to disk='''+savedialog1.FileName+''' with init';
      adoquery1.ExecSQL;
      application.MessageBox('数据库备份成功','警告',MB_OK);
    end;
    end;//恢复
    在查询分析器中运行
    use master
    goif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_killspid]
    GOcreate 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
    goprocedure TForm23.Button2Click(Sender: TObject);
    begin
    if opendialog1.Execute then
    begin
    adoquery1.SQL.Text:='use master;exec p_killspid mydatabase;Restore database madatabase From disk='''+opendialog1.FileName+''';Use mydatabase';
    adoquery1.ExecSQL;
    application.MessageBox('数据库完成恢复','警告',MB_OK);
    end;
    end;
      

  5.   

    在查询分析器中执行的那一段是要到SQL server 2000里去做的吗?
      

  6.   

    试着把CONN关闭一下再连接,再执行。
      

  7.   

    现在恢复的结果正确了,是这样的,因为我认为我已在进行恢复操作前将adoconnection连接到了master数据库,且在执行时没提示数据库正在使用,所以我就没写'exec p_killspid mydatabase'这条语句,因为我认为这条语句的作用是杀死要恢复的那个数据库,但是还是不太明白为什么没写这条语句,就不能正确恢复呢?
    另一个问题就是在master数据库中定义的这一存储过程如何打包到要发布的程序中去呢?
      

  8.   

    你不是有建数据库的sql语句吗?把这一存储过程和数据库的语句写在一起啊
    如果只是单个实例运行,且企业管理器里没有打开mydatabase,且只有你的一个程序连接到mydatabase,就可以不写'exec p_killspid mydatabase'这条语句
      

  9.   

    wnsr:谢谢你!
    我没有建数据库的SQL语句,数据库是事先建好的,不是在程序中用SQL语句建立的,再就是这一存储过程是应建立在master数据库中的吧,在程序中如何实现呢,可以将这一存储过程的建立代码给我详细写一下吗,因我刚学不久,先谢过了.
    我应该是单个实例运行且企业管理器里也没有打开mydatabase,且只有当前这一个程序连接到mydatabase,但若不写这条语句的话,就不能正确恢复,写了,就可以
      

  10.   

    上面第二点说得不详细,应该是这样的:
    我应该是单个实例运行且企业管理器里也没有打开mydatabase,且只有当前这一个程序连接到mydatabase,但若不写这条语句的话,执行了'恢复',数据库的内容实际上并没有恢复,写了,数据库的内容就真正恢复了.感觉困惑???
      

  11.   

    什么事先建好数据库啊?你难道去客户那里打开企业管理器建立数据库然后建立表吗?一般都是将所有建数据库、表、存储过程的语句写成sql脚本,然后在查询分析器中执行。