Cómo soltar la base de datos en modo de usuario único

12

¿Cómo elimino una base de datos que se muestra DatabaseName (Single User)como su nombre?

Cuando intento eliminarlo, aparece el siguiente error:

Alter falló para la base de datos 'DatabaseName'. (Microsoft.SqlServer.Smo)

La declaración ALTER DATABASE falló. (Microsoft SQL Server, error: 5064)

Traté de ejecutar lo ALTERsiguiente y todavía tengo el mismo problema.

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

Respuestas:

23

Si va a descartar una base de datos, debe ser la única conexión a esa base de datos. Si hay otras conexiones, no puede soltarlo. Desde el mensaje de error (ese error significa que su base de datos está en modo Single_User pero ya hay una conexión, por lo que no puede conectarse) mi suposición aquí es que trató de configurarla en modo Single_User y luego intentó hacer la caída pero tampoco tomó una conexión que no conocía, o algún otro proceso tiene. El hecho de que reiniciar SSMS funcionó para ti me dice que probablemente fue que estabas tomando esa conexión. Así que aquí es cómo puedes arreglar eso.

Lógicamente, debe volver a poner la base de datos en modo multiusuario para que pueda volver a ponerla en modo usuario único (pero esta vez tendrá el control de esa conexión única permitida y soltará la base de datos antes de que algo más se conecte) y luego su base de datos vete

En el código aquí es cómo debe hacer esto ( pero primero cierre las ventanas de consulta que están conectadas a esa base de datos. Reinicie SSMS y asegúrese de no seleccionar esta base de datos en el 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
fuente
Esta solución no funcionará si la base de datos ya está en modo de usuario único e intenta acceder a ella desde otra conexión.
Maxim Paukov
44
Así es, Maxim: por eso dije que mi suposición aquí, basada en la información proporcionada y la respuesta automática de los OP, es en realidad la que tiene la conexión abierta, probablemente a través del explorador de objetos o una ventana de consulta ... otro usuario, entonces tendría que encontrar esa conexión que robó la conexión única permitida y luego eliminar la sesión de esa conexión y seguir los pasos descritos anteriormente ...
Mike Walsh
13

Si intenta acceder a la base de datos que ya está en el modo de usuario único, primero debe cerrar todas las conexiones a la base de datos; de lo contrario, recibirá un mensaje de error:

Msg 5064, Nivel 16, Estado 1, Línea 1 No se pueden realizar cambios en el estado u opciones de la base de datos 'DatabaseName' en este momento. La base de datos está en modo de usuario único y actualmente hay un usuario conectado a ella. Msg 5069, Nivel 16, Estado 1, Línea 1 La instrucción ALTER DATABASE falló.

La siguiente consulta mata los procesos que acceden a la base de datos:

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

Entonces debería poder volver a poner la base de datos en modo multiusuario como de costumbre:

ALTER DATABASE 'DatabaseName' SET MULTI_USER
Maxim Paukov
fuente
2
Esta es una solución muy, muy engorrosa y equivale a un juego frustrante de whack-a-mole en un sistema ocupado. Para expulsar a todos los usuarios, mucho más fácil de usar ALTER DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATEcomo lo muestra la respuesta de Mike.
Aaron Bertrand
1
La solución de @AaronBertrand Mike no funcionará si la base de datos ya está en modo de usuario único e intenta acceder a ella desde otra conexión.
Maxim Paukov
2
Bien, si ese es el caso, él tendría que encontrar las sesiones como usted ha descrito. Sin embargo, si la conexión que configuró la base de datos para usuario único es suya ...
Aaron Bertrand