如何关闭现有的数据库连接?

63

我想关闭与 MS SQL Server 的现有连接,以便可以通过程序实现对该数据库的还原。


7个回答

109

这将断开其他所有用户的连接,只留下你自己:

alter database YourDb set single_user with rollback immediate

注意:不要忘记

alter database YourDb set MULTI_USER

完成后!


20
做完后不要忘记运行ALTER DATABASE YourDb SET MULTI_USER - Tyler Forsythe
显然,第一条语句并不总是有效地断开所有连接。至少对我来说不是这样。我必须先终止连接到数据库的进程。 - TT.
5
我已经解决了这个问题。我在这里阅读到(https://dba.stackexchange.com/a/157921/65699)使用以下语句可能有助于我的情况:`Alter database your_db_name set OFFLINE with rollback immediate`。 - TT.

18
还原向导中,点击“关闭目标数据库的现有连接”。
分离数据库向导中,点击“删除连接”选项。

1
这个选项并不总是可用的。 - Squazz
3
对于那些想知道为什么该选项并不总是可用的人,有一个解决方法。如果在执行还原对话框中的任何其他操作之前,先转到选项选项卡并勾选“关闭现有连接”复选框,则似乎可以解决该选项变灰的问题。 - Grady Werner
断开连接解决了我的问题。谢谢。 - undefined

7
我在这里找到了这个脚本: http://awesomesql.wordpress.com/2010/02/08/script-to-drop-all-connections-to-a-database/
DECLARE @dbname NVARCHAR(128)
SET @dbname = 'DB name here'
 -- db to drop connections 
DECLARE @processid INT 
SELECT  @processid = MIN(spid)
FROM    master.dbo.sysprocesses
WHERE   dbid = DB_ID(@dbname) 
WHILE @processid IS NOT NULL 
    BEGIN 
        EXEC ('KILL ' + @processid) 
        SELECT  @processid = MIN(spid)
        FROM    master.dbo.sysprocesses
        WHERE   dbid = DB_ID(@dbname) 
    END

1
在我看来,这是一种不必要的复杂和低效的方法。@Andomar的答案可以用更少的努力实现相同的目标,并且对正在进行的事务具有更好的暴力控制。它还不会捕获在已弃用的sysprocesses视图中报告了不同数据库但仍在当前数据库上持有锁定的用户。 - Aaron Bertrand
3
感谢亚伦每周对我的指责,尽管这会破坏进程,但并不是很优雅。 - Vinnie
3
这不是关于羞耻,而是要提供有价值的解决方案,不仅针对楼主,也针对未来的读者。如果一个解决方案存在缺陷,我认为应该指出来。 - Aaron Bertrand
1
@Andomar的回答并没有帮助,因为连接已经打开了!这个脚本运行得非常好! - user523650
@Haz 如果使用静态游标重写此命令,速度会更快。 - Anton Shepelev
显示剩余2条评论

4

您可以这样使用光标:

USE master
GO

DECLARE @SQL AS VARCHAR(255)
DECLARE @SPID AS SMALLINT
DECLARE @Database AS VARCHAR(500)
SET @Database = 'AdventureWorks2016CTP3'

DECLARE Murderer CURSOR FOR
SELECT spid FROM sys.sysprocesses WHERE DB_NAME(dbid) = @Database

OPEN Murderer

FETCH NEXT FROM Murderer INTO @SPID
WHILE @@FETCH_STATUS = 0

    BEGIN
    SET @SQL = 'Kill ' + CAST(@SPID AS VARCHAR(10)) + ';'
    EXEC (@SQL)
    PRINT  ' Process ' + CAST(@SPID AS VARCHAR(10)) +' has been killed'
    FETCH NEXT FROM Murderer INTO @SPID
    END 

CLOSE Murderer
DEALLOCATE Murderer

我在这里的博客中写了关于此的内容:http://www.pigeonsql.com/single-post/2016/12/13/Kill-all-connections-on-DB-by-Cursor


3

Stev.org 提供的完美解决方案: http://www.stev.org/post/2011/03/01/MS-SQL-Kill-connections-by-host.aspx

(此链接为英文原文,需要使用翻译工具进行翻译)
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[KillConnectionsHost]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[KillConnectionsHost]
GO


/****** Object:  StoredProcedure [dbo].[KillConnectionsHost]    Script Date: 10/26/2012 13:59:39 ******/

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[KillConnectionsHost] @hostname varchar(MAX)
AS
    DECLARE @spid int
    DECLARE @sql varchar(MAX)

    DECLARE cur CURSOR FOR
        SELECT spid FROM sys.sysprocesses P
            JOIN sys.sysdatabases D ON (D.dbid = P.dbid)
            JOIN sys.sysusers U ON (P.uid = U.uid)
            WHERE hostname = @hostname AND hostname != ''
            AND P.spid != @@SPID

    OPEN cur

    FETCH NEXT FROM cur
        INTO @spid

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT CONVERT(varchar, @spid)

        SET @sql = 'KILL ' + RTRIM(@spid)
        PRINT @sql
        EXEC(@sql)

        FETCH NEXT FROM cur
            INTO @spid
    END

    CLOSE cur
    DEALLOCATE cur
GO

这是一个相当长的内容,但这也是唯一对我有效的解决方案!谢谢 - curiousBoy

2

简短回答:

您只能在“数据库上下文>>还原向导”中找到“关闭目标数据库的现有连接”选项,而不能在任何特定数据库的上下文中找到该选项

详细回答:

右键单击您服务器名称下方的数据库,如下所示:

并从中选择“还原数据库...”选项。

db

在“还原数据库”向导中,

  1. 选择要还原的数据库之一
  2. 在左侧垂直菜单中,单击“选项

db1

在这里,您可以找到一个复选框,上面写着“关闭目标数据库的现有连接

db3

只需勾选它,就可以进行还原操作。

完成还原后,它会自动恢复所有连接。


0
在SQL Server Management Studio的更新版本中,您现在可以右键单击数据库并选择“Take Database Offline”选项。这将使您有选择地断开与数据库的所有活动连接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接