Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法获得独占访问权限,因为数据库正在使用中_C#_Sql_Tsql_Database Restore - Fatal编程技术网

C# 无法获得独占访问权限,因为数据库正在使用中

C# 无法获得独占访问权限,因为数据库正在使用中,c#,sql,tsql,database-restore,C#,Sql,Tsql,Database Restore,我正在使用以下代码恢复数据库 void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath) { string sRestore = "USE [master] RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + "' WITH FILE = 1, NOUNLOAD, S

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

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'."

我如何修复它?

这个问题的原因是不言而喻的(与当前打开/活动的数据库的连接),但是使用以下方法(也使用谷歌搜索它,以便您理解它)就可以了:

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数据库数据库名 使用回滚设置单个用户 立即行动

-这将使它只能连接到数据库的一个连接 …制造的 -运行以下命令以查看任何重复连接到的位置 数据库来自

EXEC SP_WHO2
执行秘书2

-检查此列表,在DBName列下查找。如果数据库是 列出,检查程序名,然后单击 主机名列以查看谁是 正在尝试连接。 -如果它不是一个服务,或其他应用程序,将自动 请注意,重新连接可以关闭的设备 要终止的SPID列中的数字 连接,并立即开始 备份。将下面的SPID替换为 只是电话号码

KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
杀死SPID恢复数据库 来自磁盘的数据库名= 'X:\PATHTO\BACKUP.BAK'GO

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

ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO
更改数据库名称集 具有回滚立即转到功能的多用户


只有在数据库没有任何连接(除了您的连接)的情况下,才能进行恢复。在MS SQL Server上启动所有用户的简单方法是:

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO
现在,您可以执行恢复而不受惩罚。确保在完成恢复后将其设置回多用户模式:

ALTER DATABASE [MyDB] SET Multi_User
GO

因此,我编写了以下方法来恢复我的数据库,
我这样做对吗

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";
    }
}
最佳方法

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 
现在数据库已准备好进行恢复


更多()

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

sqlServer.KillAllProcesses("databaseName");
  • 只能与数据库建立一个连接-运行以下命令以查看到数据库的任何重复连接来自何处

    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
    

-1表示剽窃。编辑下面的文字直接摘自TheOneBlackMage的回答:“打电话给互联网警察,我犯了一个错误,现在我引用网站来尝试救赎自己”1。查看编辑历史记录,您在我发布评论后添加了超链接。2.你知道为什么在我发表评论后,我的其他一些答案立即遭到4票反对吗?剽窃(来自维基百科):“错误地盗用、模仿、盗用和发表另一位作者的语言、思想、想法或表达,并将其作为自己的原创作品。”我的数据库在
D:\SQL\RRDB.mdf
中,我必须用完整路径替换
MyDB
,或者干脆
RRDB.mdf
?我让数据库成为单用户,但我面临着同样的问题!您必须在语句末尾添加“With Rollback Immediate”;这会在断开连接时立即回滚所有挂起的事务。只需将其设置为单用户,默认情况下将保持连接打开,直到事务完成。这对我不起作用。我得到同样的错误“无法获得独占访问权…”原则上对我来说很好。我无法运行它,但没有明显的错误。请记住,“将单个用户设置为立即回滚”将关闭所有连接(运行该命令的连接除外),并回滚所有事务。set OFFLINE&set ONLINE也适用于SQL 2008。请注意,这两项工作必须连续进行;如果数据库脱机,则无法还原。如果数据库脱机,则可以还原。我在更新的2008 R2上测试了它,它成功了。通常,上述方法不起作用,您必须使用活动监视器终止活动会话。