none
Saber si se ejecuto correctamente el procedimiento almacenado RRS feed

  • Pregunta

  • Buenos días equipo de su apoyo con lo siguiente: tengo un proyecto en vb 2017 en donde tengo 4 capas capadatos, capaentidades,capanegocio y capapresentacion

    en la capadatos tengo lo sigueinte:

     Public Sub AgregarEmpleado(ByVal registros As EntidadEmpleados)
            Using cnn As New SqlConnection(My.Settings.cn)
                cnn.Open()
    
                Dim cmd As New SqlCommand("P_InsertarEmpleado", cnn)
                cmd.CommandType = CommandType.StoredProcedure
    
                With cmd.Parameters
                    .AddWithValue("@idempleado", registros.idempleado)
                    .AddWithValue("@codigo_empleado", registros.codigo_empleado)
                    .AddWithValue("@nombres", registros.nombres)
                    .AddWithValue("@apellidos", registros.apellidos)
                    .AddWithValue("@cedula", registros.cedula)
                    .AddWithValue("@fecha_nacimiento", registros.fecha_nacimiento)
                    .AddWithValue("@direccion", registros.direccion)
                    .AddWithValue("@sexo", registros.sexo)
                    .AddWithValue("@celular", registros.celular)
                    .AddWithValue("@fecha_entrada", registros.fecha_entrada)
                    .AddWithValue("@foto", registros.foto)
                End With
                cmd.ExecuteNonQuery()
    
                Dim proc As Boolean = Convert.ToBoolean(cmd.ExecuteNonQuery)
                If proc = True Then
                    MsgBox("Datos Guardados Correctamente", MsgBoxStyle.Information, "Econtrol")
                Else
                    MsgBox("Ha Ocurrido Un Error Al Querer Guardad Los Datos", MsgBoxStyle.Information, "Econtrol")
                End If
    
                cnn.Dispose()
                cnn.Close()
            End Using
        End Sub


    en la capa entidades

    Imports System.IO
    Public Class EntidadEmpleados
        Private _idempleado As Integer
        Public Property idempleado
            Get
                Return _idempleado
            End Get
            Set(value)
                _idempleado = value
            End Set
    
        End Property
    
        Private _codigo_empleado As String
        Public Property codigo_empleado
            Get
                Return _codigo_empleado
            End Get
            Set(value)
                _codigo_empleado = value
            End Set
    
        End Property
    
        Private _nombres As String
        Public Property nombres
            Get
                Return _nombres
            End Get
            Set(value)
                _nombres = value
            End Set
    
        End Property
    
        Private _apellidos As String
        Public Property apellidos
            Get
                Return _apellidos
            End Get
            Set(value)
                _apellidos = value
            End Set
    
        End Property
    
        Private _cedula As String
        Public Property cedula
            Get
                Return _cedula
            End Get
            Set(value)
                _cedula = value
            End Set
    
        End Property
    
        Private _fecha_nacimiento As DateTime
        Public Property fecha_nacimiento
            Get
                Return _fecha_nacimiento
            End Get
            Set(value)
                _fecha_nacimiento = value
            End Set
    
        End Property
    
        Private _direccion As String
        Public Property direccion
            Get
                Return _direccion
            End Get
            Set(value)
                _direccion = value
            End Set
    
        End Property
    
        Private _sexo As String
        Public Property sexo
            Get
                Return _sexo
            End Get
            Set(value)
                _sexo = value
            End Set
    
        End Property
    
        Private _celular As String
        Public Property celular
            Get
                Return _celular
            End Get
            Set(value)
                _celular = value
            End Set
    
        End Property
    
    
        Private _fecha_entrada As DateTime
        Public Property fecha_entrada
            Get
                Return _fecha_entrada
            End Get
            Set(value)
                _fecha_entrada = value
            End Set
    
        End Property
    
        Private _foto As Byte()
        Public Property foto() As Byte()
            Get
                Return _foto
            End Get
            Set(ByVal value As Byte())
                _foto = value
            End Set
        End Property
    
    
    
    End Class


    en la capanegocio 

    Imports CapaDatos
    Imports CapaEntidades
    Public Class NegocioEmpleado
    
        Public Sub NuevoEmpleado(ByVal registro As EntidadEmpleados)
            Dim datos As New DatosEmpleados
            datos.AgregarEmpleado(registro)
        End Sub
    End Class


    en la capapresentacion

     Private Sub AgregarEmpleado()
            Try
    
                Dim entidad As New EntidadEmpleados
                Dim negocio As New NegocioEmpleado
                With entidad
                    .idempleado = IDEMPlEADO
                    .codigo_empleado = Me.txtidempleado.Text
                    .nombres = Me.txtnombres.Text
                    .apellidos = Me.txtapellidos.Text
                    .cedula = Me.txtcedula.Text
                    .fecha_nacimiento = Me.txtfechaNacimiento.Text
                    .direccion = Me.txtdireccion.Text
                    .sexo = Me.txtsexo.Text
                    .celular = Me.txtcelular.Text
                    .fecha_entrada = Me.txtfechaContrato.Text
                    .foto = ImageHelper.ImageToByteArray(Me.pbfoto.Image)
    
                End With
                negocio.NuevoEmpleado(entidad)
    
            Catch expSQL As Exception
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
            End Try
        End Sub


    en el boton guardar

     Private Sub btnguardarEditar_Click(sender As Object, e As EventArgs) Handles btnguardarEditar.Click
            Try
    
                Select Case CasoGuardarEmpleado
                    Case 1
    
                        If Me.txtnombres.Text = "" Or Me.txtapellidos.Text = "" Or Me.txtsexo.Text = "" Or Me.txtcedula.Text = "" Or Me.txtfechaNacimiento.Text = "" Or Me.txtdireccion.Text = "" Or Me.txtcelular.Text = "" Or Me.txtfechaContrato.Text = "" Or Me.txtusuario.Text = "" Or Me.txtcontraseña.Text = "" Or Me.txtrol.Text = "" Then
                            MsgBox("Revise Campos Vavios Porfavor", MsgBoxStyle.Exclamation, "Econtrol")
                            Call MostrarSi()
                            Me.txtnombres.Focus()
                            Return
                        Else
                            Call AgregarEmpleado()
                           Call LimpiarControles()
                            Call CargarListaEmpleados()
                        End If
    
                    Case 2
    
                End Select
    
            Catch expSQL As Exception
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
            End Try
        End Sub


    entonces al dar clip en el boton guardar quiero que me salga un mesaje para el usuario indicandole que se han guardados los datos y en caso contrario que le indique que se produjo un error , pero no se como saber si el procedimiento se ejecuto correctamente en la capa de datos despues de ejecutar el procedimiento almacenado tengo lo siguiente

     Dim proc As Boolean = Convert.ToBoolean(cmd.ExecuteNonQuery)
                If proc = True Then
                    MsgBox("Datos Guardados Correctamente", MsgBoxStyle.Information, "Econtrol")
                Else
                    MsgBox("Ha Ocurrido Un Error Al Querer Guardad Los Datos", MsgBoxStyle.Information, "Econtrol")
                End If

    lo cual me funciona pero solo cuando se guarda corectamente y cuando pasa algun erro no me manda el mensaje de error, yo quisiera que a demas de eso del mensaje tambien me revocara la ejecucion.....

    miércoles, 7 de noviembre de 2018 15:52

Respuestas

  • Ojo, esto que haces fallará muchísio:

    Dim proc As Boolean = Convert.ToBoolean(cmd.ExecuteNonQuery)

    Lo que devuelve el ExecuteNonQuery es el número de filas afectadas por la última sentencia ejecutada dentro del procedimiento. Convertir eso a Boolean no te sirve para saber si el procedimiento se ejecutó correctamente, salvo que sepas con toda seguridad que la última sentencia del procedimiento siempre afecta a 0 filas cuando el proceso falla.

    Ye recomendaría como solución más sencilla lanzar una excepción y dejar que se propague por el stack. El procedimiento puede hacer un THROW (o RAISERROR si la BD es antigua) en caso de error, o directamente no hacer nada si es sencillo y no tiene try...catch y tiene un XACT_ABORT). La excepción devuelta por el procedimiento se puede propagar a través de tus capas hasta que la interceptes en la capa de datos. Si quieres, por elegancia, puedes capturar el SqlException en capa de datos y re-disparar una nueva excepción interna de tu programa, para que no llege a las capas superiores el propio SqlException, que no pertenece a esas capas.

    • Propuesto como respuesta Pablo Rubio miércoles, 7 de noviembre de 2018 17:44
    • Marcado como respuesta Reynaldo Sanchez miércoles, 7 de noviembre de 2018 21:24
    miércoles, 7 de noviembre de 2018 17:13
  • En la capa de datos mete algo así:

    Try
        cmd.ExecuteNonQuery()
    Catch ex As SqlException
        Throw New Exception("Error en capa de datos") 'Mete aquí la información que quieras propagar
    End Try
    

    Eso lo que hace es "sustituir" el SqlException (que pertenece a capa de datos) por otro Exception (puede ser una excepción personlaizada si lo deseas) para "subirlo" a otras capas.

    Por cierto, ten cuidado: En la subrutina original que pusiste al principio de todo tienes dos llamadas a cmd.ExecuteNonquery. Asegúrate de poner una sola.

    En el resto de las capas y/o métodos de cada capa, asegúrate de que no pones un try...catch, o si lo pones, que haga un nuevo Throw dentro del Catch. Así hasta llegar al sitio donde quieras presentar el error, y ahí sí que pones un Try...Catch "auténtico" que intercepte todas las excepciones y muestre el pertinente mensaje.

    • Marcado como respuesta Reynaldo Sanchez miércoles, 7 de noviembre de 2018 21:25
    miércoles, 7 de noviembre de 2018 18:44
  • me sale el mensaje DE EXCEPCIÓN QUE E PUESTO EN LA CAPA DE DATOS MAS LA EXCEPCIÓN QUE GENERA EL TRY EN EL BOTÓN ELIMINAR

    Síguelo con el debugger. Tal como está escrito en el código que has mostrado, solo puede salir el mensaje del botón, porque no existe en ningún otro sitio ninguna instrucción que muestre ningún otro mensaje. Si te sale otro mensaje, tiene que haber en algún sitio un MsgBox que lo muestre, en el en código fuente no se ve. Sigue la ejecución paso a paso con el debugger hasta encontrar en qué punto se produce el otro mensaje.

    MANDARLE AL USUARIO EN CASO DE QUE SE ELIMINE CORRECTAMENTE UN MSGBOX INDICÁNDOLE LA ELIMINACIÓN FUE EXITOSA-MENTE Y EN CASO CONTRARIO INDICÁNDOLE LA EXCEPCIÓN 

    Bueno, eso es trivial: simplemente pon el mensaje que indica "éxito" al final del Try. Si no falla nada, se mostrará ese mensaje. Si falla, saltará al Catch y por lo tanto mostrará el mensaje del Catch en lugar del otro.

    • Marcado como respuesta Reynaldo Sanchez miércoles, 7 de noviembre de 2018 21:26
    miércoles, 7 de noviembre de 2018 20:55
  • No. Quiere decir exactamente lo contrario: En capa de datos ES OBLIGATORIO que haya un try...catch que intercepte las Excepciones en capa de datos y las traduzca a otras excepciones que no sean de capa de datos.

    Editado: Es decir, significa que en capa de datos tiene que existir el codigo siguiente, que ya habiamos metido antes y que ya estaba probado:

    Try
        cmd.ExecuteNonQuery()
    Catch ex As SqlException
        Throw New Exception("Error en capa de datos") 'Mete aquí la información que quieras propagar
    End Try

    Donde hay que hacer el cambio es unicamente en la capa de presentacion, en la cual no debe existir nada que "hable" acerca de la capa de datos. Precisamente para eso en la capa de datos hemos traducido la excepcion a otra distinta, para que no le lleguen a la capa de datos unas excepciones de mas bajo nivel que no tienen por que ser conocidas en la capa mas alta. Piensa que la capa de presentacion ni siquiera deberia tener un "Imports" del System.data.Sql, por lo que deberia dar un error de compilacion si utilizases un SqlException en dicha capa.


    viernes, 9 de noviembre de 2018 16:20

Todas las respuestas

  • Ojo, esto que haces fallará muchísio:

    Dim proc As Boolean = Convert.ToBoolean(cmd.ExecuteNonQuery)

    Lo que devuelve el ExecuteNonQuery es el número de filas afectadas por la última sentencia ejecutada dentro del procedimiento. Convertir eso a Boolean no te sirve para saber si el procedimiento se ejecutó correctamente, salvo que sepas con toda seguridad que la última sentencia del procedimiento siempre afecta a 0 filas cuando el proceso falla.

    Ye recomendaría como solución más sencilla lanzar una excepción y dejar que se propague por el stack. El procedimiento puede hacer un THROW (o RAISERROR si la BD es antigua) en caso de error, o directamente no hacer nada si es sencillo y no tiene try...catch y tiene un XACT_ABORT). La excepción devuelta por el procedimiento se puede propagar a través de tus capas hasta que la interceptes en la capa de datos. Si quieres, por elegancia, puedes capturar el SqlException en capa de datos y re-disparar una nueva excepción interna de tu programa, para que no llege a las capas superiores el propio SqlException, que no pertenece a esas capas.

    • Propuesto como respuesta Pablo Rubio miércoles, 7 de noviembre de 2018 17:44
    • Marcado como respuesta Reynaldo Sanchez miércoles, 7 de noviembre de 2018 21:24
    miércoles, 7 de noviembre de 2018 17:13
  • Ye recomendaría como solución más sencilla lanzar una excepción y dejar que se propague por el stack. El procedimiento puede hacer un THROW (o RAISERROR si la BD es antigua) en caso de error, o directamente no hacer nada si es sencillo y no tiene try...catch y tiene un XACT_ABORT)................

    En el procedimiento almacenado hago eso a como te lo muestro a continuación :

    create procedure P_EliminarEmpleado
     @idempleado as int
     as
    begin
           BEGIN TRANSACTION;
    	BEGIN TRY
    		-- Eliminamos el contenido
    		DELETE FROM dbo.Empleados WHERE dbo.Empleados.idempleado = @idempleado;
     	-- Confirmamos la transaccion
    		COMMIT TRANSACTION;
    	END TRY
    	BEGIN CATCH
    		-- Deshacemos la transaccion
    		ROLLBACK TRANSACTION;
     
    		-- Variables para capturar el error
    		DECLARE @ErrorMensaje NVARCHAR(4000);
    		DECLARE @ErrorSeveridad INT;
    		DECLARE @ErrorEstado INT;
     
    		-- Capturamos el Error
    		SELECT @ErrorMensaje = ERROR_MESSAGE(),
    			   @ErrorSeveridad = ERROR_SEVERITY(),
    			   @ErrorEstado = ERROR_STATE();
     
    		-- Usamos RAISERROR dentro del bloque CATCH para expandir
    		-- la información del error original y lo lanzamos
    		-- para que la aplicacion cliente se entere de lo sucedido
    		RAISERROR (@ErrorMensaje, -- El mensaje
    		           @ErrorSeveridad, -- La severidad
    			   @ErrorEstado -- El estado
    		          );
    	END CATCH;
    end


    ***************************

    La excepción devuelta por el procedimiento se puede propagar a través de tus capas hasta que la interceptes en la capa de datos. Si quieres, por elegancia, puedes capturar el SqlException en capa de datos y re-disparar una nueva excepción interna de tu programa, para que no llege a las capas superiores el propio SqlException, que no pertenece a esas capas.

    Esta parte de propagación es la que no logro asimilar muy bien sería bueno que me explicar en un ejemplo por favor....



    miércoles, 7 de noviembre de 2018 17:47
  • En la capa de datos mete algo así:

    Try
        cmd.ExecuteNonQuery()
    Catch ex As SqlException
        Throw New Exception("Error en capa de datos") 'Mete aquí la información que quieras propagar
    End Try
    

    Eso lo que hace es "sustituir" el SqlException (que pertenece a capa de datos) por otro Exception (puede ser una excepción personlaizada si lo deseas) para "subirlo" a otras capas.

    Por cierto, ten cuidado: En la subrutina original que pusiste al principio de todo tienes dos llamadas a cmd.ExecuteNonquery. Asegúrate de poner una sola.

    En el resto de las capas y/o métodos de cada capa, asegúrate de que no pones un try...catch, o si lo pones, que haga un nuevo Throw dentro del Catch. Así hasta llegar al sitio donde quieras presentar el error, y ahí sí que pones un Try...Catch "auténtico" que intercepte todas las excepciones y muestre el pertinente mensaje.

    • Marcado como respuesta Reynaldo Sanchez miércoles, 7 de noviembre de 2018 21:25
    miércoles, 7 de noviembre de 2018 18:44
  • hola fíjate que he probado y no me resulta lo hice de la siguiente manera, pero me funciona solo si o si en EL evento clip del botón eliminar pongo la sentencia dentro de un try a como te lo muestro en el código que te anexo y ademas me sale el mensaje DE EXCEPCIÓN QUE E PUESTO EN LA CAPA DE DATOS MAS LA EXCEPCIÓN QUE GENERA EL TRY EN EL BOTÓN ELIMINAR Y NO SE VE NADA BIEN, ADEMAS LO QUE BUSCO YO ES MANDARLE AL USUARIO EN CASO DE QUE SE ELIMINE CORRECTAMENTE UN MSGBOX INDICÁNDOLE LA ELIMINACIÓN FUE EXITOSA-MENTE Y EN CASO CONTRARIO INDICÁNDOLE LA EXCEPCIÓN  O INDICÁNDOLE QUE HAY UN ERROR...

    'capa datos
    
     Public Sub EliminarEmpleado(ByVal registros As EntidadEmpleados)
            Try
                Using cnn As New SqlConnection(My.Settings.cn)
                    cnn.Open()
    
                    Dim cmd As New SqlCommand("P_EliminarEmpleado", cnn)
                    cmd.CommandType = CommandType.StoredProcedure
    
                    With cmd.Parameters
                        .AddWithValue("@idempleado", registros.idempleado)
                    End With
    
                    cmd.ExecuteNonQuery()
    
                    cnn.Close()
                    cnn.Dispose()
                End Using
            Catch ex As SqlException
                Throw New Exception("Para eliminar datos de un empleado antes debe de borrar sus datos en la cuenta de usuario") 'Mete aquí la información que quieras propagar
            End Try
    
        End Sub
    
    'capa entidades
    Imports System.IO
    Public Class EntidadEmpleados
        Private _idempleado As Integer
        Public Property idempleado
            Get
                Return _idempleado
            End Get
            Set(value)
                _idempleado = value
            End Set
    
        End Property
    
        Private _codigo_empleado As String
        Public Property codigo_empleado
            Get
                Return _codigo_empleado
            End Get
            Set(value)
                _codigo_empleado = value
            End Set
    
        End Property
    
        Private _nombres As String
        Public Property nombres
            Get
                Return _nombres
            End Get
            Set(value)
                _nombres = value
            End Set
    
        End Property
    
        Private _apellidos As String
        Public Property apellidos
            Get
                Return _apellidos
            End Get
            Set(value)
                _apellidos = value
            End Set
    
        End Property
    
        Private _cedula As String
        Public Property cedula
            Get
                Return _cedula
            End Get
            Set(value)
                _cedula = value
            End Set
    
        End Property
    
        Private _fecha_nacimiento As DateTime
        Public Property fecha_nacimiento
            Get
                Return _fecha_nacimiento
            End Get
            Set(value)
                _fecha_nacimiento = value
            End Set
    
        End Property
    
        Private _direccion As String
        Public Property direccion
            Get
                Return _direccion
            End Get
            Set(value)
                _direccion = value
            End Set
    
        End Property
    
        Private _sexo As String
        Public Property sexo
            Get
                Return _sexo
            End Get
            Set(value)
                _sexo = value
            End Set
    
        End Property
    
        Private _celular As String
        Public Property celular
            Get
                Return _celular
            End Get
            Set(value)
                _celular = value
            End Set
    
        End Property
    
    
        Private _fecha_entrada As DateTime
        Public Property fecha_entrada
            Get
                Return _fecha_entrada
            End Get
            Set(value)
                _fecha_entrada = value
            End Set
    
        End Property
    
        Private _foto As Byte()
        Public Property foto() As Byte()
            Get
                Return _foto
            End Get
            Set(ByVal value As Byte())
                _foto = value
            End Set
        End Property
    
    
    
    End Class
    
    'capa negocio
    
    Imports CapaDatos
    Imports CapaEntidades
    
    Public Class NegocioEmpleado
    
        Public Sub NuevoEmpleado(ByVal registro As EntidadEmpleados)
            Dim datos As New DatosEmpleados
            datos.AgregarEmpleado(registro)
        End Sub
        Public Sub ModificarEmpleado(ByVal registros As EntidadEmpleados)
            Dim Datos As New DatosEmpleados
            Datos.ActualizarEmpleado(registros)
        End Sub
    
        Public Sub EliminarEmpleado(ByVal registros As EntidadEmpleados)
            Dim Datos As New DatosEmpleados
            Datos.EliminarEmpleado(registros)
        End Sub
    
    End Class
    
    'capa presentacion
    
     Private Sub EliminarEmpleado()
    
            Dim entidad As New EntidadEmpleados
                Dim negocio As New NegocioEmpleado
                With entidad
                    .idempleado = IdEmpleadoEliminar
                End With
                negocio.EliminarEmpleado(entidad)
    
        End Sub
    
    en el boton eliminar
    Try
                If IdEmpleadoEliminar = 0 Then
                    MsgBox("Seleccione un registro Por Favor", MsgBoxStyle.Exclamation, "Econtrol")
                    Return
                Else
                    Call EliminarEmpleado()
                    Call CargarListaEmpleados()
                    Call ClearControles()
                    Call MostrarNo()
                End If
                IdEmpleadoEliminar = 0
                Me.txtsearch.Clear()
    
            Catch expSQL As Exception
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
            End Try
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    













    miércoles, 7 de noviembre de 2018 19:54
  • me sale el mensaje DE EXCEPCIÓN QUE E PUESTO EN LA CAPA DE DATOS MAS LA EXCEPCIÓN QUE GENERA EL TRY EN EL BOTÓN ELIMINAR

    Síguelo con el debugger. Tal como está escrito en el código que has mostrado, solo puede salir el mensaje del botón, porque no existe en ningún otro sitio ninguna instrucción que muestre ningún otro mensaje. Si te sale otro mensaje, tiene que haber en algún sitio un MsgBox que lo muestre, en el en código fuente no se ve. Sigue la ejecución paso a paso con el debugger hasta encontrar en qué punto se produce el otro mensaje.

    MANDARLE AL USUARIO EN CASO DE QUE SE ELIMINE CORRECTAMENTE UN MSGBOX INDICÁNDOLE LA ELIMINACIÓN FUE EXITOSA-MENTE Y EN CASO CONTRARIO INDICÁNDOLE LA EXCEPCIÓN 

    Bueno, eso es trivial: simplemente pon el mensaje que indica "éxito" al final del Try. Si no falla nada, se mostrará ese mensaje. Si falla, saltará al Catch y por lo tanto mostrará el mensaje del Catch en lugar del otro.

    • Marcado como respuesta Reynaldo Sanchez miércoles, 7 de noviembre de 2018 21:26
    miércoles, 7 de noviembre de 2018 20:55
  • Hola Pablo fijate que he solucionado lo que quería de la siguiente manera bueno me esta funcionando míralo y me dices como lo vez...si esta bien o no..

    en la capa datos 

     Public Sub EliminarEmpleado(ByVal registros As EntidadEmpleados)
            Try
                Using cnn As New SqlConnection(My.Settings.cn)
                    cnn.Open()
    
                    Dim cmd As New SqlCommand("P_EliminarEmpleado", cnn)
                    cmd.CommandType = CommandType.StoredProcedure
    
                    With cmd.Parameters
                        .AddWithValue("@idempleado", registros.idempleado)
                    End With
    
                    cmd.ExecuteNonQuery()
    
                    MsgBox("Registro Eliminado Correctamente", MsgBoxStyle.Information, "Econtrol")
    
                    cnn.Close()
                    cnn.Dispose()
                End Using
            Catch ex As SqlException
                Throw New Exception("Para eliminar datos de un empleado antes debe de borrar sus datos en la cuenta de usuario")
            End Try
    
        End Sub

    y en el boton eliminar de la capa presentacion

     Private Sub btneliminar_Click(sender As Object, e As EventArgs) Handles btneliminar.Click
            Try
                If IdEmpleadoEliminar = 0 Then
                    MsgBox("Seleccione un registro Por Favor", MsgBoxStyle.Exclamation, "Econtrol")
                    Return
                Else
                    Call EliminarUsuario()
                    Call EliminarEmpleado()
                    Call CargarListaEmpleados()
                    Call ClearControles()
                    Call MostrarNo()
                End If
                IdEmpleadoEliminar = 0
                Me.txtsearch.Clear()
    
            Catch expSQL As Exception
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
            End Try
        End Sub

    miércoles, 7 de noviembre de 2018 20:57
  • A simple vista parece correcto, pero te hago una observación: En la capa de presentación no deberías mostrar "SQL Exception" en el mensaje. La idea de la programación en capas es que deberías poder sustituir una capa sin que las demás se vean afectadas. Por ejemplo, podrías sustituir la capa de datos por otra capa que en lugar de grabar en SQL grabe en un fichero de texto, o que grabe a través de una servicio web. En ese caso no habría ningún "SQL Exception", lo que habría (desde el punto de vista de la capa de presentación) es un error de grabación. Ese es el motivo por el que en la capa de datos hemos interceptado el SqlException y hemos devuelto a cambio un Exception, precisamente para que la capa de presentación no tenga que saber nada acerca de "Sql".
    jueves, 8 de noviembre de 2018 7:22
  • Es correcto, tu enfoque es el que yo quisiera implementar pero no me funciona si yo quito el "SQL Exception" en la capa de presentación me sale el siguiente errror

    jueves, 8 de noviembre de 2018 17:52
  • ¡NO! Has quitado el "Catch" entero. No es eso lo que hay que quitar. Hay que quitar el TEXTO que dice "SQL Exception" y en su lugar poner otra cosa como por ejemplo "Error de grabación". La capa de datos no debe hacer ninguna mención a "SQL", porque ella no "sabe" si más abajo en la capa de datos se está usando SQL o se está usando cualquier otra cosa, así que hay que poner mensajes genéricos en los que no figure la palabra "SQL".

    Por elegancia probablemente deberías también renombrar la variable (aunque el nombre de la variable es "mudo" y el programa funciona igual con independencia de que tenga cualquier nombre), así que en lugar de "Catch expSQL As Exception" podrías poner, por ejemplo, "Catch exp As Exception".

    jueves, 8 de noviembre de 2018 18:07
  • No me funciona....ya lo intente y nada!
    jueves, 8 de noviembre de 2018 22:29
  • Tiene que funcionar con toda seguridad. Mira a ver si lo que has puesto es algo como lo siguiente y de no ser así, examina las diferencias:

     Private Sub btneliminar_Click(sender As Object, e As EventArgs) Handles btneliminar.Click
            Try
                If IdEmpleadoEliminar = 0 Then
                    MsgBox("Seleccione un registro Por Favor", MsgBoxStyle.Exclamation, "Econtrol")
                    Return
                Else
                    Call EliminarUsuario()
                    Call EliminarEmpleado()
                    Call CargarListaEmpleados()
                    Call ClearControles()
                    Call MostrarNo()
                End If
                IdEmpleadoEliminar = 0
                Me.txtsearch.Clear()
                MessageBox.Show("La grabación se realizó con éxito")
            Catch exp As Exception
                MsgBox(exp.Message, MsgBoxStyle.OkOnly, "Se produjo un error")
            End Try
        End Sub

    viernes, 9 de noviembre de 2018 6:28
  • Quiere decir que en la capa de datos no puede ir ningun try Catch
    viernes, 9 de noviembre de 2018 13:56
  • No. Quiere decir exactamente lo contrario: En capa de datos ES OBLIGATORIO que haya un try...catch que intercepte las Excepciones en capa de datos y las traduzca a otras excepciones que no sean de capa de datos.

    Editado: Es decir, significa que en capa de datos tiene que existir el codigo siguiente, que ya habiamos metido antes y que ya estaba probado:

    Try
        cmd.ExecuteNonQuery()
    Catch ex As SqlException
        Throw New Exception("Error en capa de datos") 'Mete aquí la información que quieras propagar
    End Try

    Donde hay que hacer el cambio es unicamente en la capa de presentacion, en la cual no debe existir nada que "hable" acerca de la capa de datos. Precisamente para eso en la capa de datos hemos traducido la excepcion a otra distinta, para que no le lleguen a la capa de datos unas excepciones de mas bajo nivel que no tienen por que ser conocidas en la capa mas alta. Piensa que la capa de presentacion ni siquiera deberia tener un "Imports" del System.data.Sql, por lo que deberia dar un error de compilacion si utilizases un SqlException en dicha capa.


    viernes, 9 de noviembre de 2018 16:20
  • Gracias ya asimile y me funciona ..
    viernes, 9 de noviembre de 2018 22:46