Everyday hay un pequeño problema que nos da satisfacciones cuando lo podemos solucionar, el del dia de ayer, estuvo centrado en la creación dinámica de bases de datos sin utilizar ISQL y Sql scripts. Una solución fue usar SqlCommand, y ejecutar un script para el DROP y el CREATE de la Base de datos
|
DROP DATABASE MyDBPrueba CREATE DATABASE MyDBPrueba
|
Sin embargo, uno de los problemas que tiene la ejecución de este script se da cuando hay algún usuario conectado a la Base de Datos; en este caso no se puede DROPPEAR la misma.
La solución a este problema puede ser este SQL script que elimina todos los procesos asociados a una base de datos.
|
USE master; DECLARE curkillproc CURSOR FOR SELECT spid,dbs.name AS dbname FROM master..sysprocesses pro, master..sysdatabases dbs WHERE pro.dbid = dbs.dbid AND dbs.name = ‘MyDBPrueba’ FOR READ ONLY
DECLARE @varspid AS integer DECLARE @vardbname AS varchar(256) DECLARE @numUsers AS integer SET @numUsers = 0 OPEN curkillproc FETCH NEXT FROM curkillproc INTO @varspid, @vardbname WHILE @@fetch_status = 0 BEGIN EXEC(‘kill ‘ + @varspid) SET @numUsers = @numUsers + 1 FETCH NEXT FROM curkillproc INTO @varspid, @vardbname END CLOSE curkillproc DEALLOCATE curkillproc SELECT @numUsers as NumUsersDisconnected
|
Si lo traducimos a una function C#, puede quedar de la siguiente manera
|
/// <summary> /// Disconnects the users from data base. /// </summary> /// <param name="sqlConnection">The SQL connection.</param> /// <param name="databaseName">Name of the database.</param> /// <param name="commandTimeout">The command timeout.</param> /// <returns>The number of users disconected.</returns> private int DisconnectUsers(SqlConnection sqlConnection, string databaseName, int commandTimeout) { string query = string.Format(CultureInfo.InvariantCulture, "USE master; \r\nDECLARE curkillproc \r\nCURSOR FOR SELECT \r\n spid,dbs.name AS dbname \r\n FROM \r\nmaster..sysprocesses pro, \r\n master..sysdatabases dbs \r\n WHERE \r\n pro.dbid = dbs.dbid AND \r\n dbs.name = ‘{0}’ \r\n FOR READ ONLY \r\n \r\n DECLARE @varspid AS integer \r\n DECLARE @vardbname AS varchar(256) \r\n DECLARE @numUsers AS integer \r\nSET @numUsers = 0 \r\n OPEN curkillproc \r\n FETCH NEXT FROM \r\n curkillproc \r\n INTO @varspid, @vardbname \r\nWHILE @@fetch_status = 0 \r\nBEGIN \r\n EXEC(‘kill ‘ + @varspid) \r\n SET @numUsers = @numUsers + 1 \r\n FETCH NEXT FROM curkillproc \r\n INTO @varspid, @vardbname \r\n END \r\nCLOSE curkillproc \r\nDEALLOCATE curkillproc \r\n SELECT @numUsers as NumUsersDisconnected \r\n", databaseName); SqlCommand cmd = new SqlCommand(query, sqlConnection); cmd.CommandTimeout = commandTimeout; try { return (int)cmd.ExecuteScalar(); } catch { throw; } }
|
Espero que les sea útil.
Saludos
El Bruno
PD: No hace falta que recuerde que en el caso de eliminar todas las conexiones abiertas contra una base de datos, debemos tener un cuidado especial para no reventar algún proceso importante contra la misma. Y que este codigo es un rejunte de conocimiento recolectado de diferentes artículos leidos en la Web, si puedo reuno a todas las "sources" :D.
Leave a comment