none
sp_detach_db - Error en marcar la base como en uso RRS feed

  • Pregunta

  • Estimado Foro:

    Estoy desarrollando un formulario que me permita adjuntar o separar un archivo de base de datos SQL Server desde VB 2010.

    La anexión no tiene problemas, pero cuando deseo desvincular una base de datos, me genera el siguiente error: 

    No se puede separar la base de datos base de datos 'My Base'; está en uso.

    El código que utilizo para desvincular esta base, es el siguiente:

    Try
                Using conn As New SqlConnection("Persist Security Info=False;Integrated Security=true;Initial Catalog=master;server=" & cboServidor.Text.Trim)
                    conn.Open()
                    Using cmd As New SqlCommand("sp_detach_db", conn)
                        cmd.CommandType = CommandType.StoredProcedure
                        cmd.Parameters.AddWithValue("@dbname", cboBases.Text.Trim)
                        cmd.ExecuteNonQuery()
                    End Using
                End Using
            Catch ex As System.Data.SqlClient.SqlException
                MsgBox(ex.Message & vbCrLf & ex.GetType.FullName & vbCrLf & "Intente esta acción desde el Microsoft SQL Management Studio", MsgBoxStyle.Critical, "Borrado cancelado")
            End Try

    Cuando me acusa este error, voy a SQL Management y ejecuto la siguiente consulta:

    USE master

    EXEC sp_who2

    Me el siguiente resultado:

    La base marcada, es la que intento desvincular, y me acusa ese estado. No tengo usado ningún software, ni abierta la base, solo que este servidor permite conexiones remotas (aunque no se encuentre en uso). Si desvinculo desde el Management, no tengo ningún problema, y se desvincula inmediatamente.

    Muchas gracias de antemano.


    Juan Carlos

    lunes, 13 de mayo de 2013 12:51

Respuestas

Todas las respuestas

  • si analizas la doc

    sp_detach_db (Transact-SQL)

    veras que dice:

    To force current users out of the database immediately or within a specified number of seconds, also use the ROLLBACK option: ALTER DATABASE database_name SET SINGLE_USER WITH ROLLBACK rollback_option. For more information, see ALTER DATABASE (Transact-SQL).

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    lunes, 13 de mayo de 2013 13:12
  • Muchas gracias Leandro, como siempre, muy atento:

    Tu ayuda me permitió solucionar el problema de esta manera:

    Try
                Using conn As New SqlConnection("Persist Security Info=False;Integrated Security=true;Initial Catalog=master;server=" & cboServidor.Text.Trim)
                    conn.Open()
                    Using cmd As New SqlCommand("ALTER DATABASE [" & cboBases.Text.Trim & "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;", conn)
                        cmd.ExecuteNonQuery()
                    End Using
                    Using cmd As New SqlCommand("sp_detach_db", conn)
                        cmd.CommandType = CommandType.StoredProcedure
                        cmd.Parameters.AddWithValue("@dbname", cboBases.Text.Trim)
                        cmd.ExecuteNonQuery()
                    End Using
                End Using
            Catch ex As System.Data.SqlClient.SqlException
                MsgBox(ex.Message & vbCrLf & ex.GetType.FullName & vbCrLf & "Intente esta acción desde el Microsoft SQL Management Studio", MsgBoxStyle.Critical, "Borrado cancelado")
            End Try

    Lo marcado en negrita, es el código que faltaba.

    Para ayudar a otros amigos, les publico el código de vinculación de un archivo de base de datos:

    Try
                If FileSystem.Dir(Lbl_Archivo.Text & Soft.mdfFile, FileAttribute.Directory) = "" Or FileSystem.Dir(Lbl_Archivo.Text & Soft.logFile, FileAttribute.Directory) = "" Then
                    MsgBox("No se encuentran los archivos de la base de datos " & Lbl_Archivo.Text, MsgBoxStyle.Critical, "Resulta imposible instalar las bases")
                    Exit Sub
                End If
                Dim a As String = InputBox("Nombre de la base: ", "Nombre que le pondrá a la base", Lbl_Archivo.Text)
                If a = "" Then Exit Sub
    
                'Esta rutina me permite agregar a una instancia, una nueva base de datos
                Using conn As New SqlConnection("Persist Security Info=False;Integrated Security=true;Initial Catalog=master;server=" & cboServidor.Text.Trim)
                    conn.Open()
                    Using cmd As New SqlCommand("sp_attach_db", conn)
                        cmd.CommandType = CommandType.StoredProcedure
                        cmd.Parameters.AddWithValue("@dbname", a)
                        cmd.Parameters.AddWithValue("@filename1", String.Format(Cultura, "{0}{1}", Lbl_Archivo.Text, Soft.mdfFile))
                        cmd.Parameters.AddWithValue("@filename2", String.Format(Cultura, "{0}{1}", Lbl_Archivo.Text, Soft.logFile))
                        cmd.ExecuteNonQuery()
                    End Using
                End Using
                MsgBox("La base se incorporado exitosamente", MsgBoxStyle.Information, "Vuelva a leer el servidor donde lo alojó")
                cboInstancias_TextChanged(cboServidor, New System.EventArgs)
            Catch ex As Exception
                MsgBox(ex.Message & vbCrLf & ex.GetType.FullName & vbCrLf & ex.Source, MsgBoxStyle.Information, "Error controlado")
            End Try

    Por supuesto, en la variable Soft he almacenado textos que me sirven en distintos lugares, pero puede cambiarse por texto.

    Para obtener la solución, además consulté este blog a quien agradezco también:

    http://blog.sqlauthority.com/2010/02/11/sql-server-alter-database-dbname-set-single_user-with-rollback-immediate/


    Juan Carlos

    lunes, 13 de mayo de 2013 14:15