Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Server
Publicado el 13 octubre, 2012 por Angel Camilo Bernal Serna
[ad]
Cuando trabajamos con SQL server, muchas veces nos damos cuenta que las operaciones
que se van a realizar requieren acceso exclusivo. En lo personal, me ocurre generalmente
cuando trato de restaurar una base de datos sobre una base de datos que actualmente está en
uso, pero puede ocurrir con otro tipo de tareas.
La verdad es frustrante encontrar el aviso que indica que la base de datos está en uso:
Bueno, pues para este problema existen varias soluciones; en este post vamos a revisar 2 de
ellas.
Para cualquiera de las 2 soluciones que planteo, hay que tener en cuenta varios elementos:
Para el caso del método A, lo podemos llevar a cabo desde el Microsoft® SQL Server
Management Studio (MSSMS) cambiando las opciones de la base de datos:
1. Clic derecho sobre la base de datos donde deseamos cerrar las conexiones
2. En la página de “Opciones” de la ventana de propiedades, buscamos la entrada
“Restrict Access”; por defecto estará en “MULTI_USER”
3. Seteamos la opción “Restrict Access” a “SINGLE_USER” y damos “Ok”
4. Una vez damos clic en “Ok”, el motor de base de datos nos va a indicar que para
aplicar el cambio sobre la base de datos deberá cerrar todas las demás (excepto la
nuestra) conexiones a dicha base de datos, genial, esto es lo que queremos que haga.
Damos clic en “Yes” (para los que lo tengan en español, esto equivale a dar clic en
“Si” jejeje. )
5. Una vez aceptamos el motor cerrará todas las conexiones y colocará un icono
especial sobre la base de datos en la que acabamos de aplicar los cambios
Este icono nos indica que la base de datos esta en modo “Single User”.
Ahora ya podemos realizar las tareas que deseemos en la base de datos; es importante tener
en cuenta que mientras no se reverse la acción que acabamos de realizar ningún usuario
(salvo tú) va a poder tener acceso a la base de datos. Para volver a dejar la base de datos en
el estado original, basta con realizar nuevamente los pasos descritos atrás y poner en
“Restrict Access” en modo “MULTI_USER”.
Para quienes prefieran el código en vez de la interfaz gráfica, todos los pasos anteriores
tienen su equivalente en código T-SQL; en lo personal, siempre prefiero el código ya que
me obliga a estar aprendiendo nuevas sentencias día a día. He aquí el código equivalente
para pasar de “MULTI USER” A “SINGLE USER” y viceversa:
GO
GO
Para pasar de “SINGLE USER” a “MULTI USER”:
USE [master]
GO
GO
Para el caso del método B (la opción de “matar” los procesos), consiste en unas sencillas
sentencias T-SQL y hacer uso de la instrucción “Kill”, que como su nombre lo indica (y
como lo indica también la documentación de MSDN en: http://msdn.microsoft.com/es-
es/library/ms173730.aspx) se encarga de “Matar” o terminar los procesos y/o las
conexiones “normales”.
Dado que la instrucción “Kill” debe recibir como parámetro los ID’s de las sesiones de
cuyos procesos se van a cerrar, podemos hacer una consulta a la tabla “SysProcesses” de la
base de datos “Master” para tener la lista de procesos activos asociados a la base de datos
que necesitamos; para filtrar los resultados de la consulta a fin de matar solamente los
procesos de nuestra base de datos, vamos a utilizar el campo “DBId” (el id de la base de
datos). Para extraer el nombre como tal de la base de datos, podemos hacer uso de la
función DB_NAME() que recibe como parámetro el Id de la base de datos. Como para
matar los procesos solo necesitamos el Id del proceso, este se encuentra en el campo spid
de la tabla “SysProcesses”. Al final, la lista de procesos a “matar” la obtendremos del
siguiente query:
Ahora, para evitarnos la tarea de matar uno por uno los procesos, podemos crear una
instrucción que se encargue de matar los procesos del query por nosotros, lo anterior, lo
logramos creando una instrucción “kill” por cada registro resultante y luego concatenar
todos los “kill” en una cadena de texto que al final ejecutaremos con el comando “exec”
así:
USE[Master]
GO
FROM
master..SysProcesses
WHERE DB_NAME(DBId)=‘{NOMBRE_DE_TU_BASE_DE_DATOS}’
PRINT @KillCommandSQL
–EXEC (@KillCommandSQL)
Bueno amigos, esto es todo, espero esta entrada pueda ser de ayuda en algún momento y
que los pueda sacar de apuros en alguna situación que así lo requiera.
Si alguno de ustedes encuentra un error en algo que haya mencionado en esta entrada, o si
alguno tiene una idea alternativa para forzar el cierre de conexiones en SQL Server o si
quiere comentar como se haría en otras plataformas, por favor no dude en colocar un
comentario al final de esta entrada.