단일 사용자 모드에서 데이터베이스를 삭제하는 방법


12

DatabaseName (Single User)이름으로 표시되는 데이터베이스를 삭제하려면 어떻게합니까 ?

삭제하려고하면 다음 오류가 발생합니다.

데이터베이스 'DatabaseName'에 대한 변경에 실패했습니다. (Microsoft.SqlServer.Smo)

ALTER DATABASE 문이 실패했습니다. (Microsoft SQL Server, 오류 : 5064)

나는 ALTER아래 를 실행하려고했지만 여전히 같은 문제가 있습니다.

ALTER DATABASE [DatabaseName] SET MULTI_USER WITH NO_WAIT

답변:


23

데이터베이스를 삭제하려는 경우 해당 데이터베이스에 대한 유일한 연결이어야합니다. 다른 연결이 있으면 삭제할 수 없습니다. 오류 메시지에서 (이 오류는 데이터베이스가 Single_User 모드에 있지만 이미 연결되어 있으므로 연결할 수 없음을 의미합니다) 내 가정은 Single_User 모드로 설정하려고 시도한 후 삭제를 시도했지만 당신이 알지 못하거나 다른 프로세스가 가지고있는 연결을 잡았습니다. SSMS를 다시 시작하면 효과가 있다는 사실을 알 수 있습니다. 이를 해결하는 방법은 다음과 같습니다.

논리적으로 데이터베이스를 다시 다중 사용자 모드로 설정해야 단일 데이터베이스를 다시 단일 사용자 모드로 전환 할 수 있습니다 (그러나 이번에는 허용 된 단일 연결을 제어하고 다른 것이 연결되기 전에 데이터베이스를 삭제함). 없어

다음 코드는이 작업을 수행하는 방법입니다 ( 그러나 먼저 해당 데이터베이스에 연결된 쿼리 창을 닫습니다. SSMS를 다시 시작하고 개체 브라우저에서이 데이터베이스를 선택하지 않았는지 확인하십시오 ).

-- Then attempt to take your database to multi_user mode, do this from master
USE MASTER 
GO

ALTER DATABASE myDatabaseName 
SET multi_user WITH ROLLBACK IMMEDIATE
GO

-- Now put it into single_user mode and drop it. Use Rollback Immediate to disconnect any sessions and rollback their transactions. Safe since you are about to drop the DB.
ALTER DATABASE myDatabaseName
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

DROP DATABASE myDatabaseName
GO

데이터베이스가 이미 단일 사용자 모드에 있고 다른 연결에서 액세스하려고하면이 솔루션이 작동하지 않습니다.
Maxim Paukov 2016

4
맞습니다. Maxim-여기에 제공된 정보와 OPs 자체 답변을 기반으로 한 내 가정은 실제로 객체 탐색기 또는 쿼리 창을 통해 열린 연결이있는 것으로 가정했습니다 ... 일부 다른 방법으로 열린 경우 다른 사용자의 경우 허용되는 단일 연결을 훔친 연결 하나를 찾은 다음 해당 연결 세션을 종료하고 위에서 설명한 단계를 수행해야합니다.
Mike Walsh

13

이미 단일 사용자 모드 인 데이터베이스에 액세스하려고하면 먼저 데이터베이스에 대한 모든 연결을 닫아야합니다. 그렇지 않으면 오류 메시지가 나타납니다.

메시지 5064, 수준 16, 상태 1, 줄 1 현재 데이터베이스 이름 'DatabaseName'의 상태 또는 옵션을 변경할 수 없습니다. 데이터베이스가 단일 사용자 모드에 있으며 사용자가 현재 연결되어 있습니다. 메시지 5069, 수준 16, 상태 1, 줄 1 ALTER DATABASE 문이 실패했습니다.

다음 쿼리는 데이터베이스에 액세스하는 프로세스를 죽이고 :

-- Create the sql to kill the active database connections  
declare @execSql varchar(1000), @databaseName varchar(100)  
-- Set the database name for which to kill the connections  
set @databaseName = 'DatabaseName'  

set @execSql = ''   
select  @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '  
from    master.dbo.sysprocesses  
where   db_name(dbid) = @databaseName  
     and  
     DBID <> 0  
     and  
     spid <> @@spid  
exec(@execSql)
GO

그런 다음 평소와 같이 데이터베이스를 다중 사용자 모드로 되돌릴 수 있어야합니다.

ALTER DATABASE 'DatabaseName' SET MULTI_USER

2
이것은 매우 성가신 솔루션이며 바쁜 시스템에서 whack-a-mole의 실망스러운 게임과 같습니다. ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATEMike의 답변이 보여주는 것처럼 모든 사용자를 쫓아 내기가 훨씬 쉽습니다 .
Aaron Bertrand

1
@AaronBertrand Mike의 솔루션은 데이터베이스가 이미 단일 사용자 모드에 있고 다른 연결에서 액세스하려고하면 작동하지 않습니다.
Maxim Paukov 2016

2
맞다면, 당신이 설명한대로 세션을 찾아야 할 것입니다. 그러나 데이터베이스를 single_user로 설정 한 연결이 자신의 연결 인 경우 ...
Aaron Bertrand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.