290

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

如何终止与数据库的所有连接以便重命名它?

4

19 回答 19

382

Adam 建议的方法行不通的原因是,在您循环活动连接期间,可以建立新的连接,而您会错过这些连接。您可以改用以下没有此缺点的方法:

-- set your current connection to use master otherwise you might get an error

use master
ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE 

--do you stuff here 

ALTER DATABASE YourDatabase SET MULTI_USER
于 2008-08-14T19:56:56.633 回答
111

完成此操作的脚本,将“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
于 2008-08-14T19:57:15.073 回答
55

杀死它,用火杀死它:

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
于 2010-05-12T10:40:36.627 回答
27

使用 SQL Management Studio Express:

在对象资源管理器树中,在 Management 下向下钻取到“Activity Monitor”(如果在其中找不到它,则右键单击数据库服务器并选择“Activity Monitor”)。打开活动监视器,您可以查看所有进程信息。您应该能够找到您感兴趣的数据库的锁并终止这些锁,这也会终止连接。

之后您应该可以重命名。

于 2008-08-14T19:58:03.947 回答
24

我一直用:


ALTER DATABASE DB_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
GO 
SP_RENAMEDB 'DB_NAME','DB_NAME_NEW'
Go 
ALTER DATABASE DB_NAME_NEW  SET MULTI_USER -- set back to multi user 
GO 
于 2008-08-14T20:00:23.427 回答
21
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE

ALTER DATABASE [Test]
SET ONLINE
于 2012-07-18T08:02:36.680 回答
14

下线需要一段时间,有时我会遇到一些问题。

我认为最可靠的方式:

分离 右键单击​​ DB -> 任务 -> 分离...检查“删除连接”确定

重新 附加 右键单击​​数据库 -> 附加.. 添加... -> 选择您的数据库,然后将附加为列更改为您想要的数据库名称。行

于 2011-01-05T14:49:27.437 回答
6
Select 'Kill '+ CAST(p.spid AS VARCHAR)KillCommand into #temp
from master.dbo.sysprocesses p (nolock)
join master..sysdatabases d (nolock) on p.dbid = d.dbid
Where d.[name] = 'your db name'

Declare @query nvarchar(max)
--Select * from #temp
Select @query =STUFF((                              
            select '  ' + KillCommand from #temp
            FOR XML PATH('')),1,1,'') 
Execute sp_executesql @query 
Drop table #temp

使用“主”数据库并运行此查询,它将终止数据库中的所有活动连接。

于 2012-02-01T09:30:22.690 回答
5

当我尝试恢复数据库时,我通常会遇到该错误我通常只是转到 Management Studio 中树的顶部,然后右键单击并重新启动数据库服务器(因为它在开发机器上,这在生产中可能并不理想)。这是关闭所有数据库连接。

于 2008-08-15T15:52:24.463 回答
4

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

于 2008-08-14T19:56:56.540 回答
4

以下是如何在 MS SQL Server Management Studio 2008 中可靠地执行此类操作(也可能适用于其他版本):

  1. 在对象资源管理器树中,右键单击根数据库服务器(带有绿色箭头),然后单击活动监视器。
  2. 打开活动监视器中的进程选项卡,选择“数据库”下拉菜单,然后按所需的数据库进行过滤。
  3. 右键单击对象资源管理器中的数据库并启动“任务-> 脱机”任务。让这个在后台运行,而你...
  4. 尽可能安全地关闭。
  5. 从进程选项卡中终止所有剩余进程。
  6. 使数据库重新联机。
  7. 重命名数据库。
  8. 使您的服务重新联机并将其指向新数据库。
于 2010-11-12T04:30:46.740 回答
4

另一种“用火杀死它”的方法是重新启动 MSSQLSERVER 服务。我喜欢从命令行做事。将其准确粘贴到 CMD 中即可:NET STOP MSSQLSERVER & NET START MSSQLSERVER

或者打开“services.msc”,找到“SQL Server (MSSQLSERVER)”并右键单击,选择“重新启动”。

这将“肯定,肯定”终止与该实例上运行的所有数据库的所有连接。

(我比许多更改和更改服务器/数据库上的配置的方法更喜欢这个)

于 2011-08-18T22:16:24.600 回答
3

在这种情况下为我工作的选项如下:

  1. 对有问题的数据库启动“分离”操作。这将打开一个窗口(在 SQL 2005 中),显示阻止对 DB 执行操作的活动连接。
  2. 终止活动连接,取消分离操作。
  3. 数据库现在应该可用于恢复。
于 2011-12-28T09:18:26.237 回答
2

试试这个:

ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
于 2008-08-14T19:58:13.777 回答
2

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

于 2010-11-15T11:13:29.100 回答
2

这些对我不起作用(SQL2008 Enterprise),我也看不到任何正在运行的进程或连接到数据库的用户。重新启动服务器(右键单击 Management Studio 中的 Sql Server 并选择重新启动)允许我恢复数据库。

于 2012-05-01T03:10:41.877 回答
2

我正在使用 SQL Server 2008 R2,我的数据库已经设置为单用户,并且有一个连接限制了对数据库的任何操作。因此,推荐的 SQLMenace 的解决方案以错误响应。这是在我的情况下工作的一个

于 2012-06-12T11:04:08.253 回答
0

我使用 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;
于 2015-05-07T09:42:40.280 回答
-1

您可以使用 SP_Who 命令并杀死所有使用您的数据库的进程,然后重命名您的数据库。

于 2014-06-02T09:58:11.040 回答