Como descartar banco de dados no modo de usuário único

12

Como eu largo um banco de dados que aparece DatabaseName (Single User)como seu nome?

Quando tento excluí-lo, recebo o seguinte erro:

Alter falhou no banco de dados 'DatabaseName'. (Microsoft.SqlServer.Smo)

A instrução ALTER DATABASE falhou. (Microsoft SQL Server, erro: 5064)

Tentei executar o ALTERabaixo e ainda tenho o mesmo problema.

ALTER DATABASE [DatabaseName] SET MULTI_USER WITH NO_WAIT
Prasad Kanaparthi
fonte

Respostas:

23

Se você deseja descartar um banco de dados, deve ser a única conexão com esse banco de dados. Se houver outras conexões, não será possível descartá-la. Na mensagem de erro (esse erro significa que seu banco de dados está no modo Usuário Único, mas já existe uma conexão para que você não possa se conectar), suponho aqui que você tentou configurá-lo para o modo Usuário Único e tentou fazer o descarte, mas você pegou uma conexão que você não conhecia, ou que algum outro processo possui. O fato de reiniciar o SSMS funcionou para você me diz que provavelmente foi você que pegou essa conexão. Então, aqui está como você pode consertar isso.

Logicamente, é necessário colocar o banco de dados novamente no modo multiusuário, para que você possa colocá-lo novamente no modo de usuário único (mas desta vez você estará no controle dessa conexão única permitida e descartará o banco de dados antes que outra coisa se conecte) e, em seguida, seu banco de dados será se foi.

No código, aqui está como você precisa fazer isso ( mas primeiro feche as janelas de consulta que estão conectadas a esse banco de dados. Reinicie o SSMS e verifique se você não selecionou esse banco de dados no navegador de objetos ):

-- 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
Mike Walsh
fonte
Essa solução não funcionará se o banco de dados já estiver no modo de usuário único e você tentar acessá-lo de outra conexão.
Maxim Paukov
4
Isso mesmo, Maxim - foi por isso que eu disse que minha suposição aqui com base nas informações fornecidas e na resposta automática dos OPs é na verdade a que possui a conexão aberta, provavelmente através do explorador de objetos ou de uma janela de consulta ... Se foi aberta de alguma outra maneira por alguns outro usuário, você teria que descobrir que uma conexão que roubou a conexão única permitida e, em seguida, interromper a sessão de uma conexão e seguir as etapas descritas acima. #
Mike Walsh
13

Se você tentar acessar o banco de dados que já está no modo de usuário único, será necessário fechar todas as conexões com o banco de dados primeiro; caso contrário, você receberá uma mensagem de erro:

Msg 5064, Nível 16, Estado 1, Linha 1 Alterações no estado ou nas opções do banco de dados 'DatabaseName' não podem ser feitas no momento. O banco de dados está no modo de usuário único e um usuário está atualmente conectado a ele. Mensagem 5069, nível 16, estado 1, linha 1 instrução ALTER DATABASE falhou.

A consulta a seguir mata os processos que acessam o banco de dados:

-- 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

Em seguida, você poderá trazer o banco de dados de volta ao modo multiusuário, como de costume:

ALTER DATABASE 'DatabaseName' SET MULTI_USER
Maxim Paukov
fonte
2
Essa é uma solução muito, muito complicada e equivale a um jogo frustrante de dar um tapa em um sistema ocupado. Para expulsar todos os usuários, muito mais fácil de usar, ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATEcomo mostra a resposta de Mike.
Aaron Bertrand
1
A solução do @AaronBertrand Mike não funcionará se o banco de dados já estiver no modo de usuário único e você tentar acessá-lo de outra conexão.
Maxim Paukov
2
Certo, se for esse o caso, ele teria que encontrar as sessões como você descreveu. No entanto, se a conexão que definir o banco de dados para SINGLE_USER é o seu próprio ...
Aaron Bertrand