답변:
제거하려는 DB의 데이터베이스 스냅 샷과 같은 종속성이 없는지 확인하십시오. 그러나 오류 메시지는 다르게 보입니다. 데이터베이스에 연결되어있는 숨겨진 프로세스가 없습니까? 데이터베이스를 다른 이름으로 바꾼 후 즉시 모든 세션을 종료하는 스크립트를 실행하여 데이터베이스를 삭제하는 것이 좋습니다.
이 선택을 기반으로 커서를 만듭니다.
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')
커서 내부의 문제 :
SET @kill_process = 'KILL ' + @spid
EXEC master.dbo.sp_executesql @kill_process
PRINT 'killed spid : '+ @spid
커서가 닫히고 할당이 해제 된 후 :
sp_dboption 'my_db', 'single user', 'TRUE'
go
sp_renamedb 'my_db', 'my_db_old'
go
DROP DATABASE MY_DB_OLD
다른 데이터베이스에 연결된 세션에는 데이터베이스에 영향을주는 열린 트랜잭션이있을 수 있습니다. sp_who2는 하나의 데이터베이스 만 표시합니다. SSMS에서 개체 탐색기 또는 개체 탐색기 세부 정보를 여는 것처럼 간단 할 수도 있습니다. sp_who2에는 데이터베이스가 하나만 표시됩니다.
책임있는 세션 을 찾으려고 노력하지 마십시오 . 하나의 문장으로 모두를 죽이십시오 (그리고 다른 쿼리 창, 객체 탐색기 등이 연결된 SSMS 사본이 아닌지 확인하십시오).
USE master;
GO
ALTER DATABASE dbname SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
이제 UI를 삭제하지 않고 DDL을 사용하여 삭제할 수 있습니다.
DROP DATABASE dbname;
USE master
다음, DROP DATABASE dbname
. 분명히 필요한 것은 다른 것을 "사용"하여 db를 해제하는 것입니다.
DROP
명령 을 실행할 때 현재 데이터베이스는 무엇입니까 ? 이 시도:
use master
go
drop database mydb
go
또한 삭제하려는 데이터베이스가 sa
아닌 연결되어 있는지 확인하십시오 dbo
.
UI를 사용할 때 SSMS의 기능을보고 작업에 대한 스크립트를 발행하도록 지시하는 것은 어떻습니까? 다음은 DB를 마우스 오른쪽 버튼으로 클릭하고 삭제를 선택한 다음 확인란을 선택하여 기존 연결을 닫을 때 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
나는이 상황에 여러 번 직면했으며 아래는 내가하는 일입니다.
명백한 방법이 효과가 없을 때 ..... (현 상황에서와 같이) :
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
처음으로 작동하는 StackOverflow에서 실제로 간단한 답변을 찾았습니다.
https://stackoverflow.com/a/7469167/261405
해당 답변의 SQL은 다음과 같습니다.
DECLARE @DatabaseName nvarchar(50)
SET @DatabaseName = N'YOUR_DABASE_NAME'
DECLARE @SQL varchar(max)
SELECT @SQL = COALESCE(@SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(@DatabaseName) AND SPId <> @@SPId
--Use this to see results
SELECT @SQL
--Uncomment this to run it
--EXEC(@SQL)