我想重命名一个数据库,但不断得到“无法获得数据库上的排他锁”的错误,这意味着仍有一些连接处于活动状态。

如何杀死数据库的所有连接以便重命名它?


当前回答

杀他,用火杀他。

USE master
go

DECLARE @dbname sysname
SET @dbname = 'yourdbname'

DECLARE @spid int
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname)
WHILE @spid IS NOT NULL
BEGIN
EXECUTE ('KILL ' + @spid)
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) AND spid > @spid
END

其他回答

在对象资源管理器上的MS SQL Server Management Studio中,右键单击数据库。在下面的上下文菜单中选择“任务->脱机”

下面是如何在MS SQL Server Management Studio 2008(可能也适用于其他版本)中可靠地执行这类事情:

In the Object Explorer Tree, right click the root database server (with the green arrow), then click activity monitor. Open the processes tab in the activity monitor, select the 'databases' drop down menu, and filter by the database you want. Right click the DB in Object Explorer and start a 'Tasks -> Take Offline' task. Leave this running in the background while you... Safely shut down whatever you can. Kill all remaining processes from the process tab. Bring the DB back online. Rename the DB. Bring your service back online and point it to the new DB.

我使用sp_who来获取数据库中所有进程的列表。这样更好,因为您可能需要检查要终止哪个进程。

declare @proc table(
    SPID bigint,
    Status nvarchar(255),
    Login nvarchar(255),
    HostName nvarchar(255),
    BlkBy nvarchar(255),
    DBName nvarchar(255),
    Command nvarchar(MAX),
    CPUTime bigint,
    DiskIO bigint,
    LastBatch nvarchar(255),
    ProgramName nvarchar(255),
    SPID2 bigint,
    REQUESTID bigint
)

insert into @proc
exec sp_who2

select  *, KillCommand = concat('kill ', SPID, ';')
from    @proc

结果 您可以使用KillCommand列中的命令来终止您想要的进程。

SPID    KillCommand
26      kill 26;
27      kill 27;
28      kill 28;

右键单击数据库名称,单击属性进入属性窗口,打开选项选项卡,将“限制访问”属性从多用户更改为单用户。当你点击OK按钮时,它会提示你关闭所有打开的连接,选择“是”,你就可以将数据库重命名为....

脚本来完成这个任务,用数据库替换'DB_NAME'来杀死所有连接到:

USE master
GO

SET NOCOUNT ON
DECLARE @DBName varchar(50)
DECLARE @spidstr varchar(8000)
DECLARE @ConnKilled smallint
SET @ConnKilled=0
SET @spidstr = ''

Set @DBName = 'DB_NAME'
IF db_id(@DBName) < 4
BEGIN
PRINT 'Connections to system databases cannot be killed'
RETURN
END
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@DBName)

IF LEN(@spidstr) > 0
BEGIN
EXEC(@spidstr)
SELECT @ConnKilled = COUNT(1)
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
END