¿Cómo expulsar a los usuarios de una base de datos SQL Server 2008?

22

Necesitamos hacer una restauración, y no podemos porque otros usuarios están conectados. Pensamos que habíamos desconectado todos los procesos, pero aparentemente no.

¿Cómo podemos, desde Management Studio, dar inicio a todos los demás para que podamos hacer esta copia de seguridad?

Daniel Williams
fuente

Respuestas:

25

Hay dos formas de hacerlo:

  1. Haga clic derecho en la base de datos en el Explorador de objetos, vaya a Tareas> Separar. Seleccione la casilla de verificación Drop Connections.

  2. Establezca la base de datos en modo de usuario único como se describe aquí :

    -- hit Ctrl+Shift+M in SSMS to fill in the template parameter
    USE master;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET SINGLE_USER
    WITH ROLLBACK IMMEDIATE;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET READ_ONLY;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET MULTI_USER;
    GO
Wil
fuente
No me di cuenta que tenía tantos comentarios jajaja. Marian está en lo correcto, no es necesario ejecutar la separación real, solo obtenga el script para matar a los usuarios. @NickChammas Sí, hacer que se lea solo evita que los usuarios se vuelvan a conectar. Cuando lo configuras multiusuario puedes hacer la restauración. Además, los nombres de base de datos provienen de una plantilla y, como tales, las etiquetas como '<Nombre de la base de datos, nombre del sistema>' están destinadas a ser reemplazadas mediante el uso de Ctrl + Shift + M. En un script sin plantilla, los dbnames no tendrían comillas a su alrededor.
Wil
43

Siempre uso lo siguiente:

USE master; -- get out of dbname myself
GO
-- kick all other users out:
ALTER DATABASE [dbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- prevent sessions from re-establishing connection:
ALTER DATABASE [dbname] SET OFFLINE;

A veces esto puede llevar un tiempo, y a veces está bloqueado porque usted es el que lo ejecuta, y usted tiene una conexión activa a la base de datos . Busque otras ventanas de consulta que puedan tener el mismo contexto de base de datos; esto puede incluir diálogos abiertos, Object Explorer, IntelliSense, trabajos de larga duración, etc.

Cuando termine de hacer mis cambios en la configuración de esa base de datos, simplemente:

ALTER DATABASE [dbname] SET ONLINE;
ALTER DATABASE [dbname] SET MULTI_USER;

Aunque, a veces, lo que necesito hacer con esa base de datos requiere que la base de datos esté en línea, por lo que a veces tengo que dejarla en modo de usuario único y hacer esto:

ALTER DATABASE [dbname] SET ONLINE;
GO
USE [dbname];

Ahora puedo hacer mis cambios y, cuando esté listo para que otros usuarios se conecten, simplemente:

ALTER DATABASE [dbname] SET MULTI_USER;
Aaron Bertrand
fuente
2

Normalmente configuro la base de datos en single_user y luego espero el retraso y luego vuelvo a configurar la base de datos en multiusuario como se muestra a continuación:

-- to kill all connections for particular db ... otherwise the restore will fail as exclusive lock cannot be obtained for the db being restored.

    alter database db_name
    set single_user with rollback immediate
    waitfor delay '00:00:05'  -- wait for 5 secs
    alter database db_name
    set multi_user
    restore database db_name from disk = 'D:\restore\db_name.bak'
    with replace, stats = 10, recovery -- if you want to recover your database online
    -- optional if you dont have the same directory/file structure
    move 'datafile logical name' to 'E:\data\physical_name.mdf',
    move 'logfile logical name' to 'F:\log\physical_name_log.ldf'
Kin Shah
fuente
En realidad, no es necesario "configurar multi_usuario", ya que está ejecutando un solo script (transacción) con la instrucción de restauración. La restauración con recuperación se encargará de volver a poner la base de datos en modo multiusuario.
Svein Terje Gaup
1

Ninguna de las opciones anteriores funcionó para mí porque el servidor se vio afectado por múltiples intentos de conexión remota.

Cuando cerré el puerto de base de datos específico en el firewall de Windows, el Alter normal .. Set Multi_User funcionó en el primer intento.

olafk
fuente
-1

Lo siguiente en realidad mata todas las conexiones. Muy útil en casos donde falla el modo de usuario único

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)
Betty
fuente
1
Esto no funciona porque sysprocessesno siempre tiene en cuenta todas las sesiones que pueden contener bloqueos en esa base de datos (piense en el escenario simple donde se ejecuta una consulta en el contexto de la base de datos A pero se une a una tabla en A y una tabla en B) .
Aaron Bertrand
-1

Puede usar el script a continuación para bombardear a todos o modificar para una base de datos específica.

¡Cualquier cosa que pueda ser eliminada, lo será! Sin embargo, los SPID de servicio SQL no se verán afectados.

Drop table #who

go 

Create table #who(  [spid] int,
                    [ECID] int,
                    [Status] varchar(100),
                    [Loginname] varchar(200),
                    [Hostname] varchar(200),
                    [blk] bit,
                    dbname varchar(200),
                    cmd varchar(1000),
                    requestID int
                  )

go

Insert into #who (Spid, ECID, Status, Loginname, hostname,blk, dbname, cmd, requestid)
exec sp_who

Declare cursKillUsers Cursor for Select 'Kill ' + cast(spid as varchar(100)) + ';' [SQL] from #who where dbname like '%'
Declare @sql varchar(200)
Open cursKillUsers
Fetch next from cursKillUsers into @sql
While @@fetch_status = 0 
begin

    print @sql
    Exec (@sql)
    Fetch next from cursKillUsers into @sql

end

close cursKillUsers
deallocate cursKillUsers
BITSYSUK
fuente
-3

Yo uso este código:

ALTER DATABASE [Dbname] set offline with rollback immediate
GO
ALTER DATABASE [Dbname] set online
GO

Pero puedo ver que el ejemplo de UN SOLO USUARIO es menos de escribir.

Paul Els
fuente
3
También configurar la base de datos nuevamente en línea significa que otros usuarios pueden conectarse nuevamente antes de que comience su restauración.
Aaron Bertrand