tus*_*eau 88 sql-server-2005 sql-server
当我尝试删除数据库时,出现错误“无法删除数据库“dbname”,因为它当前正在使用中”。但是,当我运行时sp_who2,肯定没有连接到该数据库的会话。我还将数据库设置为single_user mode with rollback immediate.
为什么会这样?
Aar*_*and 103
连接到另一个数据库的会话可能有一个打开的事务,它也会影响您的数据库 - sp_who2 将只显示一个数据库。它也可以像在 SSMS 中打开的对象资源管理器或对象资源管理器详细信息一样简单,这同样只会在 sp_who2 中显示一个数据库。
不要费心去寻找负责的会话;只需用一个语句将它们全部杀死(并确保它不是您连接的 SSMS 副本,例如另一个查询窗口、对象资源管理器等):
USE master;
GO
ALTER DATABASE dbname SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
Run Code Online (Sandbox Code Playgroud)
现在您将能够删除它,并使用 DDL 而不是 UI 来做到这一点:
DROP DATABASE dbname;
Run Code Online (Sandbox Code Playgroud)
yru*_*hka 24
确保在要删除的数据库上没有诸如数据库快照之类的依赖项。但是,错误消息看起来会不同。您确定没有隐藏的进程连接到您的数据库吗?一个好的方法是运行一个脚本来终止所有会话,并在将数据库重命名为另一个名称后立即删除数据库。
基于此选择创建一个游标:
select d.name , convert (smallint, req_spid) As spid
from master.dbo.syslockinfo l,
master.dbo.spt_values v,
master.dbo.spt_values x,
master.dbo.spt_values u,
master.dbo.sysdatabases d
where l.rsc_type = v.number
and v.type = 'LR'
and l.req_status = x.number
and x.type = 'LS'
and l.req_mode + 1 = u.number
and u.type = 'L'
and l.rsc_dbid = d.dbid
and rsc_dbid = (select top 1 dbid from
master..sysdatabases
where name like 'my_db')
Run Code Online (Sandbox Code Playgroud)
光标内的问题:
SET @kill_process = 'KILL ' + @spid
EXEC master.dbo.sp_executesql @kill_process
PRINT 'killed spid : '+ @spid
Run Code Online (Sandbox Code Playgroud)
在游标关闭并释放后:
sp_dboption 'my_db', 'single user', 'TRUE'
go
sp_renamedb 'my_db', 'my_db_old'
go
DROP DATABASE MY_DB_OLD
Run Code Online (Sandbox Code Playgroud)
Gai*_*ius 20
当您发出DROP命令时,您当前的数据库是什么?尝试这个:
use master
go
drop database mydb
go
Run Code Online (Sandbox Code Playgroud)
还要确保您连接的是sa而不是dbo要删除的任何数据库。
小智 19
当您使用 UI 时只查看 SSMS 的作用,但告诉它为该操作发出脚本如何?当您右键单击数据库并选择删除,然后选中该框以关闭现有连接时,SSMS 会执行以下操作:
EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'yourdbname'
GO
USE [master]
GO
ALTER DATABASE [yourdbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
DROP DATABASE [yourdbname]
GO
Run Code Online (Sandbox Code Playgroud)
我多次遇到这种情况,以下是我所做的:
当明显的方法不起作用时......(就像你的情况一样):
从 sysdatabases 中找出数据库 ID。
然后执行 -sp_lock这将显示实例上的所有锁以及 spid 和 dbid。
使用您尝试离线或删除的 dbid 杀死 spid。
虽然这个过程有点手动,但它可以自动化如下:
IF OBJECT_ID('tempdb.dbo.#temp', 'U') IS NOT NULL
DROP TABLE #temp;
create table #temp (spid int
, dbid int
,ObjId bigint
, IndId bigint
,Type varchar(5)
,resource varchar(max)
,Mode varchar(5)
,status varchar(10));
declare @dbid int
select @dbid =DB_ID(db_name())
insert into #temp
exec sp_lock
select * from #temp
where dbid = @dbid
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
222511 次 |
| 最近记录: |