如何在sql脚本中指定“关闭现有连接”


153

我正在SQL Server 2008中对架构进行积极的开发,并且经常想重新运行我的放置/创建数据库脚本。当我跑步

USE [master]
GO

IF  EXISTS (SELECT name FROM sys.databases WHERE name = N'MyDatabase')
DROP DATABASE [MyDatabase]
GO

我经常收到这个错误

Msg 3702, Level 16, State 4, Line 3
Cannot drop database "MyDatabase" because it is currently in use.

如果右键单击对象资源管理器窗格中的数据库,然后从上下文菜单中选择“删除”任务,则有一个复选框可以“关闭现有连接”

有没有办法在脚本中指定此选项?

Answers:


247

您可以使用以下方法断开所有人的联系并回滚他们的交易:

alter database [MyDatbase] set single_user with rollback immediate

之后,您可以安全地删除数据库:)


8
我已经使用了此功能,但经常想知道是否有机会让另一个用户作为“单个用户”进入-这可能吗?可能的替代方法是ALTER DATABASE [MyDatabaseName]设置立即回滚脱机
Kristen

9
single_user中的用户是您;除非您在设置单用户模式后断开连接。然后,一(1)个其他用户可以登录。
2009年

删除数据库后,如果您使用相同的名称创建一个新数据库,我想它会处于多用户模式吗?这样就不必运行:alter database [MyDatbase] set
multi_user

@AndyM:是的,multi_user可能是默认设置
Andomar

2
@Kristen使用您的方法,我发现sql server不会删除mdf和ldf文件。设置single_user对我来说很好(我需要不断地重新创建数据库)。
2xMax 2013年

36

转到Management Studio并执行您描述的所有操作,仅单击“脚本”,而不是单击“确定”。它将显示将运行的代码,您可以将其合并到脚本中。

在这种情况下,您需要:

ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

1
我将尝试通过完全按照您的描述(编写“删除数据库”对话框的脚本)来回答此问题,但是如果您选中“关闭现有连接”复选框,则不会在脚本中添加ALTER DATABASE行。
Matt Hamilton 2009年

从向导生成的脚本包括“ alter database”行。
尼克,

奇怪的。哪个Management Studio版本?我使用的是2008 x64。
马特·汉密尔顿,

我也是:Microsoft SQL Server Management Studio 10.0.1600.22操作系统6.0.6001
尼克于2009年

8
在ALTER DATABASE未添加到脚本时出现了相同的问题。为了将其添加到脚本中,我必须确保在生成脚本时针对该数据库运行了一个进程(活动连接)。
吉尔伯特

16

根据ALTER DATABASE SET文档,在将数据库设置为SINGLE_USER模式后,您仍然有可能无法访问该数据库:

在将数据库设置为SINGLE_USER之前,请验证AUTO_UPDATE_STATISTICS_ASYNC选项是否设置为OFF。设置为ON时,用于更新统计信息的后台线程将与数据库建立连接,并且您将无法以单用户模式访问数据库。

因此,使用现有连接删除数据库的完整脚本如下所示:

DECLARE @dbId int
DECLARE @isStatAsyncOn bit
DECLARE @jobId int
DECLARE @sqlString nvarchar(500)

SELECT @dbId = database_id,
       @isStatAsyncOn = is_auto_update_stats_async_on
FROM sys.databases
WHERE name = 'db_name'

IF @isStatAsyncOn = 1
BEGIN
    ALTER DATABASE [db_name] SET  AUTO_UPDATE_STATISTICS_ASYNC OFF

    -- kill running jobs
    DECLARE jobsCursor CURSOR FOR
    SELECT job_id
    FROM sys.dm_exec_background_job_queue
    WHERE database_id = @dbId

    OPEN jobsCursor

    FETCH NEXT FROM jobsCursor INTO @jobId
    WHILE @@FETCH_STATUS = 0
    BEGIN
        set @sqlString = 'KILL STATS JOB ' + STR(@jobId)
        EXECUTE sp_executesql @sqlString
        FETCH NEXT FROM jobsCursor INTO @jobId
    END

    CLOSE jobsCursor
    DEALLOCATE jobsCursor
END

ALTER DATABASE [db_name] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE

DROP DATABASE [db_name]


2

我尝试了hgmnz在SQL Server 2012上所说的内容。

为我创建的管理:

EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'MyDataBase'
GO
USE [master]
GO
/****** Object:  Database [MyDataBase]    Script Date: 09/09/2014 15:58:46 ******/
DROP DATABASE [MyDataBase]
GO

4
这不会关闭活动连接。
詹斯

确保选中“关闭现有连接”;如果您不ROLLBACK IMMEDIATE声明,则将包括在内。在sp_delete_database_backuphistory来自选中“删除备份和还原历史记录信息数据库”。
Christian.K,

ALTER DATABASE SET SINGLE_USER ...如果没有当前连接要关闭,则选中“关闭现有连接”不会生成。
ahwm

-1

尝试使用此C#代码删除数据库

公共静态void DropDatabases(string dataBase){

        string sql =  "ALTER DATABASE "  + dataBase + "SET SINGLE_USER WITH ROLLBACK IMMEDIATE" ;

        using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["DBRestore"].ConnectionString))
        {
            connection.Open();
            using (System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, connection))
            {
                command.CommandType = CommandType.Text;
                command.CommandTimeout = 7200;
                command.ExecuteNonQuery();
            }
            sql = "DROP DATABASE " + dataBase;
            using (System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, connection))
            {
                command.CommandType = CommandType.Text;
                command.CommandTimeout = 7200;
                command.ExecuteNonQuery();
            }
        }
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.