none
Manejar errores que devuelve el SQL Server RRS feed

  • Pregunta

  • hola, consulta:

    estoy tratando de recuperar los raiserror de sql2008 desde visual studio pero no logro realizarlo

    este es el SP que estoy utilizando

    *-------------------------------------------------------------------------------------------------------------------*

    create PROCEDURE [dbo].[SP_AM_USUARIO]
    @IDUSUARIO AS INT,
    @IDROL AS INT,
    @USUARIO AS VARCHAR(25),
    @CLAVE AS VARCHAR(25),
    @CONFIRMAR  AS VARCHAR(25)
    AS

    begin

    DECLARE @COD_ERROR AS INTEGER
    DECLARE @ACTIVO AS INTEGER

    SET @ACTIVO = 1 

    IF @IDROL IS NULL OR @IDROL <= 0
    BEGIN
    RAISERROR('NO TOMÓ EL ROL DEL USUARIO.', 16, 1)
    RETURN 
    END

    IF NOT EXISTS ( SELECT * FROM dbo.ROLES WHERE IDROL = @IDROL )
    BEGIN
    RAISERROR('EL ROL ESPECIFICADO NO EXISTE.', 16, 1)
    RETURN 
    END

    IF @USUARIO IS NULL
    BEGIN
    RAISERROR('NO TOMÓ EL NOMBRE DE USUARIO.', 16, 1)
    RETURN 
    END

    IF @CLAVE IS NULL
    BEGIN
    RAISERROR('NO TOMÓ LA CLAVE DE USUARIO.', 16, 1)
    RETURN 
    END

    IF @CONFIRMAR IS NULL
    BEGIN
    RAISERROR('NO TOMÓ LA CONFIRMACIÓN DE LA CLAVE DE USUARIO.', 16, 1)
    RETURN 
    END

    IF (@CLAVE <> @CONFIRMAR)
    BEGIN
    RAISERROR('LA CLAVE DE USUARIO Y LA CLAVE DE USUARIO SON DISTINTAS.', 16, 1)
    RETURN 
    END

    BEGIN TRANSACTION

    IF EXISTS ( SELECT * FROM dbo.USUARIOS WHERE IDUSUARIO = @IDUSUARIO )
    UPDATE
    dbo.USUARIOS
    SET
    IDROL = @IDROL 
    ,USUARIO = @USUARIO 
    ,CLAVE = @CLAVE
    WHERE
    IDUSUARIO = @IDUSUARIO 

    ELSE
    INSERT dbo.USUARIOS
    (
    IDROL 
    ,USUARIO 
    ,CLAVE 
    ,ACTIVO 
    )
    VALUES
    (
    @IDROL 
    ,@USUARIO 
    ,@CLAVE 
    ,@ACTIVO 
    )


    SET @COD_ERROR = @@ERROR

    IF @COD_ERROR <> 0
    ROLLBACK TRANSACTION
    ELSE
    COMMIT TRANSACTION

    RETURN @COD_ERROR
    end

    *-------------------------------------------------------------------------------------------------------------------*

    y este es el código que eso en visual studio 2013

    Imports System.Data.SqlClient

    Public Class Form1

        Public Sub cn_InfoMessage(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)
            MsgBox("info message event: " & e.Message)
        End Sub

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Try
                Dim cn As New SqlConnection("data source=NOTEBOOK\SQLEXPRESS2008;initial catalog=dbSTOCK;integrated security=true")
                AddHandler cn.InfoMessage, AddressOf cn_InfoMessage

                cn.Open()
                Dim cmd As New SqlCommand("[SP_AM_USUARIO]")
                cmd.CommandType = CommandType.StoredProcedure
                cmd.Connection = cn

                cmd.Parameters.Add(New SqlParameter("@IDUSUARIO", SqlDbType.Int))
                cmd.Parameters.Add(New SqlParameter("@IDROL", SqlDbType.Int))
                cmd.Parameters.Add(New SqlParameter("@USUARIO", SqlDbType.VarChar, 25))
                cmd.Parameters.Add(New SqlParameter("@CLAVE", SqlDbType.VarChar, 25))
                cmd.Parameters.Add(New SqlParameter("@CONFIRMAR", SqlDbType.VarChar, 25))

                cmd.Parameters("@IDUSUARIO").Value = 1
                cmd.Parameters("@IDROL").Value = 10
                cmd.Parameters("@USUARIO").Value = "carlos"
                cmd.Parameters("@CLAVE").Value = "carlos123"
                cmd.Parameters("@CONFIRMAR").Value = "carlos12345"

                Dim myReader As SqlDataReader = cmd.ExecuteReader()

                Do
                    Do While myReader.Read()
                        MsgBox(myReader(0))
                    Loop
                Loop While myReader.NextResult()

                myReader.Close()

            Catch SqlEx As SqlException
                Dim myError As SqlError

                MsgBox("Errors Count:" & SqlEx.Errors.Count)
                For Each myError In SqlEx.Errors
                    MsgBox(myError.Number & " - " & myError.Message)
                Next
            End Try

        End Sub
    End Class

    *-------------------------------------------------------------------------------------------------------------------*

    quiero capturar los distintos raiserror y por mas que ponga algunos datos vacios o claves distintas no e da el error,

    me ejecuta el sp y ademas no me funciona el rollback.

    ayuda por favor, gracias

    carlos


    • Editado carlossauco domingo, 30 de junio de 2019 6:29
    domingo, 30 de junio de 2019 6:26

Todas las respuestas

  • Hola carlossauco:

    Si deseas obtener todos los errores antes de realizar la inserción, en cada uno de los condicionales IF, no retornes el procedure, acumula en tu contador set @coderror = @coderror + 1; después del último if retorna si  @coderror tiene un valor mayor que 0.

    Con esto conseguiras tener todos los raiserror sin intentar insertar.

    En el if de la trasacción evalúa if @@error >0

    Espero te ayude

    domingo, 30 de junio de 2019 15:15
  • hola Javi, gracias por contestar mi inquietud, he probado lo que me has dicho. lo probé desde la

    consola de sql y me tira el siguiente mensaje:

    -------------------------------------------------------------------------------------------------------

    probé esto

    SP_AM_USUARIO 7,3,'CHARLY','CHARLY1','CHARLY2'

    Mens 50000, Nivel 16, Estado 1, Procedimiento SP_AM_USUARIO, Línea 58
    LA CLAVE DE USUARIO Y LA CLAVE DE USUARIO SON DISTINTAS.

    (1 filas afectadas)

    -------------------------------------------------------------------------------------------------------

    y en el SP cambié como me has dicho

    IF @CONFIRMAR IS NULL
    BEGIN
    SET @COD_ERROR = @COD_ERROR + 1 
    RAISERROR('NO TOMÓ LA CONFIRMACIÓN DE LA CLAVE DE USUARIO.', 16, 1)
    END

    IF (@CLAVE <> @CONFIRMAR)
    BEGIN
    SET @COD_ERROR = @COD_ERROR + 1 
    RAISERROR('LA CLAVE DE USUARIO Y LA CLAVE DE USUARIO SON DISTINTAS.', 16, 1)
    END

    if @COD_ERROR > 0
    begin
    RETURN @@ERROR
    end

    BEGIN TRANSACTION

    INSERT dbo.USUARIOS
    (
    IDROL 
    ,USUARIO 
    ,CLAVE 
    ,ACTIVO 
    )
    VALUES
    (
    @IDROL 
    ,@USUARIO 
    ,@CLAVE 
    ,@ACTIVO 
    )

    IF @COD_ERROR > 0
    ROLLBACK TRANSACTION
    ELSE
    COMMIT TRANSACTION

    la verdad que no entiendo lo que estoy haciendo mal

    domingo, 30 de junio de 2019 20:47
  • Javi: ya pude lograr que funcione. como decía un viejo amigo, "no se si será la solución correcta pero funciona"

    en cada condición de los IF de validación de datos le puse a fuego lo que está en negrita:

    IF @USUARIO IS NULL OR @USUARIO = ''
    BEGIN
    SET @COD_ERROR = 1 --en vez de incrementar
    RAISERROR('NO TOMÓ EL NOMBRE DE USUARIO.', 16, 1)
    RETURN --le puse este RETURN porq sino me tira todos los errores juntos
    END

    y en visual studio me envía correctamente todos los mensajes errores en pantalla

    gracias Javi, tu aporte me sirvió mucho, gracias por compartir 

    domingo, 30 de junio de 2019 22:32