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

nic*_*ick 145 sql sql-server

我正在SQL Server 2008中对我的架构进行主动开发,并经常要重新运行我的drop/create数据库脚本.我跑的时候

USE [master]
GO

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

我经常遇到这个错误

Msg 3702, Level 16, State 4, Line 3
Cannot drop database "MyDatabase" because it is currently in use.
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*mar 236

您可以断开所有人并回滚他们的交易:

alter database [MyDatbase] set single_user with rollback immediate
Run Code Online (Sandbox Code Playgroud)

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

  • single_user中的用户就是你; 除非您在设置单用户模式后断开连接.然后一(1)个其他用户可以登录. (9认同)
  • 我已经使用了这个,但经常想知道是否有另一个用户的机会窗口作为"单个用户"进入 - 这可能吗?可能的替代方法是ALTER DATABASE [MyDatabaseName] SET OFFLINE WITH ROLLBACK IMMEDIATE (8认同)
  • @Kristen使用你的方法我发现sql server没有删除mdf和ldf文件.设置single_user对我来说很好(我需要不断重新创建数据库). (2认同)

hgm*_*mnz 36

转到管理工作室并执行您描述的所有操作,而不是单击"确定",单击"脚本".它将显示它将运行的代码,然后您可以将其合并到脚本中.

在这种情况下,您需要:

ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
Run Code Online (Sandbox Code Playgroud)

  • 有没有ALTER DATABASE相同的问题没有添加到脚本中.为了让我将它添加到脚本中,我必须确保在生成脚本时有一个进程(活动连接)针对该数据库运行. (7认同)

Ale*_*exD 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]
Run Code Online (Sandbox Code Playgroud)


小智 11

我知道为时已晚,但可能对某些人有帮助。使用此功能使您的数据库脱机

ALTER DATABASE dbname SET OFFLINE
Run Code Online (Sandbox Code Playgroud)