用于终止与数据库的所有连接的脚本(超过RESTRICTED_USER ROLLBACK)

Vac*_*ano 214 sql t-sql sql-server sql-server-2008 sql-server-2008-r2

我有一个开发数据库,​​经常从Visual Studio数据库项目(通过TFS自动构建)重新部署.

有时当我运行我的构建时,我收到此错误:

ALTER DATABASE failed because a lock could not be placed on database 'MyDB'. Try again later.  
ALTER DATABASE statement failed.  
Cannot drop database "MyDB" because it is currently in use.  
Run Code Online (Sandbox Code Playgroud)

我试过这个:

ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE
Run Code Online (Sandbox Code Playgroud)

但我仍然无法删除数据库.(我的猜测是大多数开发人员都dbo可以访问.)

我可以手动运行SP_WHO并开始查杀连接,但我需要一种自动方式在自动构建中执行此操作.(虽然这次我的连接是我试图丢弃的数据库中唯一的连接.)

是否有一个脚本可以删除我的数据库,无论谁连接?

Ale*_*exK 595

更新

对于MS SQL Server 2012及更高版本

USE [master];

DECLARE @kill varchar(8000) = '';  
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'  
FROM sys.dm_exec_sessions
WHERE database_id  = db_id('MyDB')

EXEC(@kill);
Run Code Online (Sandbox Code Playgroud)

对于MS SQL Server 2000,2005,2008

USE master;

DECLARE @kill varchar(8000); SET @kill = '';  
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), spid) + ';'  
FROM master..sysprocesses  
WHERE dbid = db_id('MyDB')

EXEC(@kill); 
Run Code Online (Sandbox Code Playgroud)

  • 这是两者的更好答案; 避免使数据库脱机,并且接受的答案并不总是有效(有时它无法回滚所有内容). (23认同)
  • 这是一个很好的答案,可以将`kill`语句聚合在一起.我会使用游标来杀死每个进程,这当然效率不高.这个答案中使用的技术很棒. (3认同)
  • 好的,快速的.唯一的问题可能是系统spid所以你可以添加WHERE dbid = db_id('My_db')和spid> 50 (3认同)

Cha*_*ins 127

USE master
GO
ALTER DATABASE database_name
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
Run Code Online (Sandbox Code Playgroud)

参考:http://msdn.microsoft.com/en-us/library/bb522682%28v=sql.105%29.aspx

  • 奇怪的是,"USE master"是关键.我试图在连接它时丢弃数据库(Duh!).谢谢! (9认同)
  • 如果使用`SET OFFLINE`,则必须手动删除db文件. (9认同)
  • 不会`更改数据库YourDatabaseName设置SINGLE_USER并立即回滚`会更好吗?如果将其设置为"OFFLINE"(如@mattalxndr所述),文件将保留在磁盘上,但是使用`SINGLE_USER`,您的连接将保留为唯一的,并且`drop database YourDatabaseName`仍将删除文件. (5认同)
  • @Keith 在脚本中,您没有连接到数据库,因此它不是“您的连接”,而是剩下的其他连接。在“set offline”之后,您可以立即发出“set online”以避免剩余文件问题(是的,存在竞争条件的可能性)。 (2认同)
  • 谢谢!我没有意识到在SQL Management Studio中使用sql语句的某个选项卡,在此数据库之前执行,导致我的数据库报告正在使用中.使用主人,去,让一切工作! (2认同)

小智 23

您可以通过执行以下操作获取SSMS提供的脚本:

  1. 右键单击SSMS中的数据库,然后选择"删除"
  2. 在对话框中,选中"关闭现有连接"复选框.
  3. 单击对话框顶部的"脚本"按钮.

该脚本将如下所示:

USE [master]
GO
ALTER DATABASE [YourDatabaseName] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
DROP DATABASE [YourDatabaseName]
GO
Run Code Online (Sandbox Code Playgroud)

  • 我不建议任何用户以单用户模式使用databse,因为这可能会导致您失去与某些应用程序用户的当前连接,而不必麻烦地找到这些用户并杀死相同或某些时间,如果到db的连接是必需的,则必须重新启动sql server如此频繁。 (2认同)

小智 7

鲜为人知:GO sql语句可以采用整数表示重复上一个命令的次数.

所以如果你:

ALTER DATABASE [DATABASENAME] SET SINGLE_USER
GO
Run Code Online (Sandbox Code Playgroud)

然后:

USE [DATABASENAME]
GO 2000
Run Code Online (Sandbox Code Playgroud)

这将重复USE命令2000次,强制所有其他连接死锁,并获得单个连接的所有权.(使您的查询窗口可以随意访问.)

  • GO不是TSQL命令,而是仅由sqlcmd和osql实用程序以及SSMS识别的特殊命令。 (2认同)