如何在单用户模式下删除数据库

Pra*_*thi 14 sql-server-2008

如何删除显示DatabaseName (Single User)为其名称的数据库?

当我尝试删除它时,出现以下错误:

更改数据库“DatabaseName”失败。(Microsoft.SqlServer.Smo)

ALTER DATABASE 语句失败。(Microsoft SQL Server,错误:5064)

我尝试执行ALTER以下操作,但仍然存在相同的问题。

ALTER DATABASE [DatabaseName] SET MULTI_USER WITH NO_WAIT
Run Code Online (Sandbox Code Playgroud)

Mik*_*lsh 26

如果您要删除一个数据库,您必须是该数据库的唯一连接。如果存在任何其他连接,则不能删除它。从错误消息(该错误意味着您的数据库处于 Single_User 模式,但已经存在连接,因此您无法连接)我的假设是您尝试将其设置为 Single_User 模式,然后尝试执行删除操作,但您要么抓住了一个你不知道的连接,或者其他一些进程。重新启动 SSMS 对您有用的事实告诉我,您可能正在获取该连接。所以这里是你如何解决这个问题。

从逻辑上讲,您必须将数据库重新置于 multi_user 模式,以便您可以再次将其置于 single_user 模式(但这次您将控制允许的单个连接并在其他连接之前删除数据库),然后您的数据库将走了。

在代码中,您需要如何执行此操作(但首先关闭连接到该数据库的查询窗口。重新启动 SSMS 并确保您没有在对象浏览器中选择此数据库):

-- Then attempt to take your database to multi_user mode, do this from master
USE MASTER 
GO

ALTER DATABASE myDatabaseName 
SET multi_user WITH ROLLBACK IMMEDIATE
GO

-- Now put it into single_user mode and drop it. Use Rollback Immediate to disconnect any sessions and rollback their transactions. Safe since you are about to drop the DB.
ALTER DATABASE myDatabaseName
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

DROP DATABASE myDatabaseName
GO
Run Code Online (Sandbox Code Playgroud)

  • 没错,Maxim - 这就是为什么我说我在这里根据提供的信息做出的假设和 OP 的自我回答实际上是可能通过对象资源管理器或查询窗口打开连接的那个......如果它被某些人以其他方式打开其他用户,那么您必须找到一个连接,该连接窃取了允许的单个连接,然后终止-那个-一个连接的会话并按照上面概述的步骤操作.. (4认同)

Max*_*kov 14

如果您尝试访问已经处于单用户模式的数据库,您需要先关闭与数据库的所有连接,否则您将收到错误消息:

消息 5064,级别 16,状态 1,第 1 行此时无法更改数据库“DatabaseName”的状态或选项。数据库处于单用户模式,当前有用户连接到它。消息 5069,级别 16,状态 1,第 1 行 ALTER DATABASE 语句失败。

下面的查询杀死访问数据库的过程:

-- Create the sql to kill the active database connections  
declare @execSql varchar(1000), @databaseName varchar(100)  
-- Set the database name for which to kill the connections  
set @databaseName = 'DatabaseName'  

set @execSql = ''   
select  @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '  
from    master.dbo.sysprocesses  
where   db_name(dbid) = @databaseName  
     and  
     DBID <> 0  
     and  
     spid <> @@spid  
exec(@execSql)
GO
Run Code Online (Sandbox Code Playgroud)

然后您应该能够像往常一样将数据库恢复到多用户模式:

ALTER DATABASE 'DatabaseName' SET MULTI_USER
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常非常麻烦的解决方案,相当于在繁忙的系统上玩令人沮丧的打地鼠游戏。要将所有用户踢出去,如 Mike 的回答所示,使用“ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATE”要容易得多。 (2认同)
  • 如果数据库已经处于单用户模式并且您尝试从其他连接访问它,@AaronBertrand Mike 的解决方案将不起作用。 (2认同)
  • 是的,如果是这种情况,他将必须找到您概述的会话。但是,如果将数据库设置为 single_user 的连接是他自己的... (2认同)