37

我正在使用以下代码来恢复数据库,

void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath)
{
    string sRestore =
        "USE [master] RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + "' WITH  FILE = 1,  NOUNLOAD,  STATS = 10";

    using (SqlConnection con = new SqlConnection(ConnectionString))
    {
        con.Open();
        SqlCommand cmdBackUp = new SqlCommand(sRestore, con);
        cmdBackUp.ExecuteNonQuery();
    }
}

但我收到以下异常

"Exclusive access could not be obtained because the database is in use.
RESTORE DATABASE is terminating abnormally.
Changed database context to 'master'."

我该如何解决?

4

6 回答 6

54

只有当数据库没有任何连接(除了你的)时,才会发生还原。在 MS SQL Server 上启动所有用户的简单方法是:

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO

现在,您可以不受惩罚地执行恢复。完成还原后,请确保将其设置回多用户模式:

ALTER DATABASE [MyDB] SET Multi_User
GO
于 2010-10-28T20:06:26.253 回答
14

因此,我编写了以下方法来恢复我的数据库,
我的方法是否正确?

void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath)
{
    using (SqlConnection con = new SqlConnection(ConnectionString))
    {
        con.Open();

        string UseMaster = "USE master";
        SqlCommand UseMasterCommand = new SqlCommand(UseMaster, con);
        UseMasterCommand.ExecuteNonQuery();

        string Alter1 = @"ALTER DATABASE [" + DatabaseFullPath + "] SET Single_User WITH Rollback Immediate";
        SqlCommand Alter1Cmd = new SqlCommand(Alter1, con);
        Alter1Cmd.ExecuteNonQuery();

        string Restore = @"RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + @"' WITH  FILE = 1,  NOUNLOAD,  STATS = 10";
        SqlCommand RestoreCmd = new SqlCommand(Restore, con);
        RestoreCmd.ExecuteNonQuery();

        string Alter2 = @"ALTER DATABASE [" + DatabaseFullPath + "] SET Multi_User";
        SqlCommand Alter2Cmd = new SqlCommand(Alter2, con);
        Alter2Cmd.ExecuteNonQuery();

        labelReport.Text = "Successful";
    }
}
于 2010-10-29T02:55:13.067 回答
9

最好的方法

Alter Database <Db_Name>  SET [SINGLE_USER | RESTRICTED_USER] 
With ROLLBACK [IMMEDIATE | AFTER 30]
go
--do your job that needs exclusive access
go
--Back to normal mode
Alter Database <Db_Name> SET MULTI_USER 
  • WITH ROLLBACK IMMEDIATE - 此选项不等待事务完成它只是开始回滚所有打开的事务
  • WITH ROLLBACK AFTER nnn - 此选项将在等待 nnn 秒以完成打开的事务后回滚所有打开的事务。在我们的示例中,我们指定进程应在回滚任何打开的事务之前等待 30 秒。

  • 当指定RESTRICTED_USER时,只有db_owner、dbcreator 或 sysadmin角色的成员可以使用数据库。MULTI_USER 将数据库返回到其正常操作状态。


第二种方式:使用 ssms 2008 R2 我们可以做同样的事情

  1. 右键单击数据库属性
  2. 转到选项-> 带有状态标题的最后一部分
  3. 更改限制SINGLE_USER的访问
  4. 对这个有用的问题回答是,这表明这种操作将关闭所有其他连接,我想这是我们在这里寻找的唯一绕过错误的东西

要更改数据库属性,SQL Server必须关闭与数据库的所有其他连接。您确定要更改属性并关闭所有其他连接吗?是还是不是

  1. 恢复你的数据库
  2. 执行步骤 1-4 将Restrict Access更改回MULTI_USER

第三种方式:以下命令也将关闭所有连接。

ALTER DATABASE [DbName] SET OFFLINE
go    
ALTER DATABASE [DbName] SET ONLINE

现在数据库已准备好恢复

更多(mssqltips:获取恢复 SQL Server 数据库的独占访问权限

于 2012-02-19T10:10:52.873 回答
8

您可以使用 SMO SqlServer 对象上的方法在执行还原之前终止指定数据库上的所有进程:

sqlServer.KillAllProcesses("databaseName");
于 2013-07-21T18:25:36.560 回答
1
  • 只能建立一个与数据库的连接。- 运行以下命令以查看与数据库的任何重复连接来自何处。

    EXEC SP_WHO2
    
  • 检查此列表,查看 DBName 列。如果列出了数据库,请检查 ProgramName 和 HostName 列以查看谁在尝试连接。

  • 如果不是服务或其他会自动重新连接且可以关闭的应用程序,请记下 SPID 列中的数字以终止连接,然后立即开始备份。仅将下面的 SPID 替换为数字。

    KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
    
  • 如果这成功完成,我们可以将新恢复的数据库设置回多用户模式。

    ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO
    
于 2013-09-10T09:39:07.340 回答
1

此问题的原因是不言而喻的(与当前打开/活动的数据库的连接),但使用以下内容(谷歌也可以理解它),它会没事的:

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

显然,用YOURDDB您的数据库名称替换并针对主数据库运行它。

哦,以防万一,如果你在单用户模式下“卡住”,这将撤消它:

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

希望这可以帮助。

编辑:

您也可以按照这个,查看连接来自哪里,以及其他信息:

我在运行将重新连接到数据库的服务时对此进行了测试。我发现您必须设置为单用户模式,然后运行 ​​sp_who2 以查看一个连接的来源,并记下 SPID。您可以在同一事务中运行该 SPID 的 kill 命令和还原,它应该会通过。这是我使用的顺序:

使用 MASTER ALTER DATABASE DATABASENAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE GO

- 这将使得只能建立一个到数据库的连接。- 运行以下命令以查看与数据库的任何重复连接来自何处。

执行 SP_WHO2

-检查此列表,查看 DBName 列。如果列出了数据库,请检查 ProgramName 和 HostName 列以查看谁在尝试连接。- 如果不是服务或其他会自动重新连接且可以关闭的应用程序,请记下 SPID 列中的数字以终止连接,并立即开始备份。仅将下面的 SPID 替换为数字。

KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO

- 如果成功完成,我们可以将新恢复的数据库设置回多用户模式。

ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO

于 2010-10-28T20:03:34.460 回答