none
retorna datos de un procedimiento almacenado RRS feed

  • Pregunta

  • Buenas gente...

               
    
    ALTER PROCEDURE [dbo].[SP_sc_TBLCLIENTE_INSERT]            
    
     -- Add the parameters for the stored procedure here       
    
     @nomEmpresa as varchar(15),    
    
     @direccion as varchar(30),    
    
     @representante as varchar(30),    
    
     @contactoTI as varchar(30)    
    
                 
    
    AS            
    
    DECLARE @loc_idCliente as numeric(3,0)
    
    
    
    BEGIN 
    
    
    
    SET @loc_idCliente=(SELECT MAX(idCliente)+1 FROM sc_tblCliente)
    
               
    
     -- SET NOCOUNT ON added to prevent extra result sets from            
    
     -- interfering with SELECT statements.            
    
     SET NOCOUNT ON;            
    
                
    
        -- Insert statements for procedure here            
    
        INSERT INTO sc_tblCliente(idCliente,nomEmpresa,direccion,representante,contactoTI)VALUES(@loc_idCliente,@nomEmpresa,@direccion,@representante,@contactoTI)        
    
        
    
        RETURN @loc_idCliente
    
    END <br/>
    
    


    intento hacer q este sp me devuelva el valor de la variable @loc_idCliente. Como lo hago??
    En codigo de vb.net tengo lo siguiente:


    Public Function ejecutaSentencia(ByVal pStrSQL As String) As String
    
            'Se declara el comando
    
            Dim cmdincluir As SqlClient.SqlCommand
    
            'Se declara la transacción para futuro uso
    
            Dim transaccion As SqlClient.SqlTransaction
    
    
    
            'Se ilustra el manejo de transacciones, sin embargo para este caso no es estrictamente necesario
    
            'Se inicia la transacción
    
            transaccion = cnConexion.BeginTransaction
    
            'Crea las instancias del comando
    
            cmdincluir = New SqlClient.SqlCommand()
    
    
    
            Try
    
                'Construye el comando Insert
    
                With cmdincluir
    
                    .Connection = cnConexion
    
                    .CommandText = pStrSQL
    
                    .CommandType = CommandType.Text
    
                    .Transaction = transaccion
    
                    .ExecuteNonQuery()
    
                End With
    
                'Si hay exito efectúa el commit
    
                transaccion.Commit()
    
            Catch excsql As SqlClient.SqlException
    
                'Si no hay exito se efectua el Rollback
    
                transaccion.Rollback()
    
                MessageBox.Show("Error (" & excsql.Number.ToString & "): " & excsql.Message, "Error de Inclusion", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
    
            Catch excgrl As Exception
    
                'Si no hay exito se efectúa el RollBack
    
                transaccion.Rollback()
    
                MessageBox.Show(excgrl.Message, "Error General", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
    
            End Try
    
        End Function<br/>
    
    



    alguien q me ayude a leer el valor devuelto por el SP.
    Agradezco la ayuda.

    salu2
    martes, 2 de junio de 2009 15:48

Respuestas

  • Y continuarás sin poder leer el valor devuelto por el procedimiento almacenado HASTA QUE NO MODIFIQUES LA FUNCIÓN "Ejecuta Sentencia", porque para poder obtener el valor, necesitas utilizar un objeto «SQLPARAMETER» con una dirección de salida (OUTPUT), tal y como te he indicado en el ejemplo.

    Debes de tener en cuenta que en Visual Basic se permite la sobrecarga de métodos, por lo que, aparte de tener tu propia función "Ejecuta Sentencia", tal cual la tienes definida, puedes añadir otra función con el mismo nombre, pero con distinto número de parámetros, es decir, la función que te he indicado anteriormente:

    Public Overloads Function ejecutaSentencia(ByVal pStrSQL As String) As String

       ' Tu función original 

    End Function


    Public Overloads Function ejecutaSentencia(ByVal nomEmpresa As String, _
                                                                   ByVal direccion As String, _
                                                                   ByVal representante As String, _
                                                                   ByVal contactoTI As String) As String

        ' La función sobrecargada

    End Function

    Si solamente llamas a la función utilizando un parámetro String, se ejecutará la primera sobrecarga de la función (tu función original), y si pasas cuatro parámetros del tipo String, se utilizará la segunda sobrecarga (la que yo te he indicado).


    Enrique Martínez [MS MVP - VB]
    martes, 2 de junio de 2009 18:59
    Moderador
  • Hola:

    Para obtener el valor devuelto por el procedimiento almacenado, deberás de modificar, tanto el procedimiento almacenado como el proedimiento que estás intentando ejecutar desde tu aplicación de Visual Basic.

    Hasta la cláusula BEGIN del procedimiento almacenado, éste se quedaría de la siguiente manera:

    ALTER PROCEDURE [dbo].[SP_sc_TBLCLIENTE_INSERT]           

     -- Add the parameters for the stored procedure here      

     @nomEmpresa as varchar(15),
     @direccion as varchar(30),
     @representante as varchar(30),
     @contactoTI as varchar(30)
     @loc_idCliente as numeric(3,0) OUT
     
     AS           

     BEGIN

     ........


    Fíjate que en lugar de declarar la variable «loc_idCliente», la he incluido en la declaración del procedimiento como un parámetro de salida.

    Ahora, la función «ejecutarSentencia» se quedaría de la manera que te indico a continuación, teniendo presente que le tendrás que pasar los parámetros que espera el procedimiento almacenado, a excepción del parámetro de salida, que será el valor que devuelva la función:


    Public Function ejecutaSentencia(ByVal nomEmpresa As String, _
                                                   ByVal direccion As String, _
                                                   ByVal representante As String, _
                                                   ByVal contactoTI As String) As String

            'Se declara la transacción para futuro uso
            Dim transaccion As SqlClient.SqlTransaction = Nothing

            Try
                'Se declara e instancia el comando
                Dim cmdincluir As New SqlClient.SqlCommand

                ' Abrimos la conexión
                cnConexion.Open()

                'Se ilustra el manejo de transacciones, sin embargo para este caso no es estrictamente necesario
                'Se inicia la transacción
                transaccion = cnConexion.BeginTransaction

                ' Construimos los parámetros del procedimiento
                Dim par As New SqlParameter("@nomEmpresa", SqlDbType.VarChar, 15)
                par.Value = nomEmpresa
                cmdincluir.Parameters.Add(par)

                par = New SqlParameter("@direccion", SqlDbType.VarChar, 30)
                par.Value = direccion
                cmdincluir.Parameters.Add(par)

                par = New SqlParameter("@representante", SqlDbType.VarChar, 30)
                par.Value = representante
                cmdincluir.Parameters.Add(par)

                par = New SqlParameter("@contactoTI", SqlDbType.VarChar, 30)
                par.Value = contactoTI
                cmdincluir.Parameters.Add(par)

                ' Creamos el parámetro de salida
                par = New SqlParameter("@loc_idcliente", SqlDbType.Decimal)
                par.Direction = ParameterDirection.Output
                cmdincluir.Parameters.Add(par)

                'Construye el comando Insert
                With cmdincluir
                    .Connection = cnConexion
                    .CommandText = "SP_sc_TBLCLIENTE_INSERT"
                    .CommandType = CommandType.StoredProcedure
                    .Transaction = transaccion
                    .ExecuteNonQuery()
                End With

                'Si hay exito efectúa el commit
                transaccion.Commit()

                Return CStr(cmdincluir.Parameters("@loc_idcliente").Value)

            Catch excsql As SqlClient.SqlException
                'Si no hay exito se efectua el Rollback
                transaccion.Rollback()
                MessageBox.Show("Error (" & excsql.Number.ToString & "): " & excsql.Message, "Error de Inclusion", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)

            Catch excgrl As Exception
                'Si no hay exito se efectúa el RollBack
                transaccion.Rollback()
                MessageBox.Show(excgrl.Message, "Error General", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)

            End Try

        End Function

    A la función la llamarías de la siguiente manera:

      ' Definimos la cadena de conexión
      '
      cnConexion = New SqlConnection("Data Source=(local);Initial Catalog=Base_Datos;Integrated Security=SSPI")

      Dim idcliente As String = ejecutaSentencia( _
                                              "valor_nombreEmpresa", _
                                              "valor_direccion", _
                                              "valor_representante", _
                                              "valor_contactoTI")

      MessageBox.Show(idcliente)

    ¡Eso es todo!

    Un saludo


    Enrique Martínez [MS MVP - VB]
    martes, 2 de junio de 2009 17:23
    Moderador
  • buenas softJaen...

    Continué buscando y me encontre q lo podia hacer de la siguiente manera:

    1. al SP le puse un "return" al final para q me retorne el valor deseado.
    2. en el codigo, en lugar de llamar a "ejecutaSentencia()" lo que hago es abrir un dataset.
    	dsDato = modPrincipal.abreDataSet(strSQL)
    	insertData = dsDato.Tables(0).Rows(0).Item("ID_CLIENTE").ToString
    Haciendo esto, abro el dataset con el valor q me retorna el SP (el codigo correspondiente a la llamada en esta en la variable strSQL) y se lo asigno a una variable de tipo string y ya lo demas es conocido.

    Agradezco muchisimo su ayuda y el tiempo q dedico a ayudarme.

    salu2
    • Marcado como respuesta waraltca martes, 9 de junio de 2009 14:33
    martes, 9 de junio de 2009 14:33

Todas las respuestas

  • Hola:

    Para obtener el valor devuelto por el procedimiento almacenado, deberás de modificar, tanto el procedimiento almacenado como el proedimiento que estás intentando ejecutar desde tu aplicación de Visual Basic.

    Hasta la cláusula BEGIN del procedimiento almacenado, éste se quedaría de la siguiente manera:

    ALTER PROCEDURE [dbo].[SP_sc_TBLCLIENTE_INSERT]           

     -- Add the parameters for the stored procedure here      

     @nomEmpresa as varchar(15),
     @direccion as varchar(30),
     @representante as varchar(30),
     @contactoTI as varchar(30)
     @loc_idCliente as numeric(3,0) OUT
     
     AS           

     BEGIN

     ........


    Fíjate que en lugar de declarar la variable «loc_idCliente», la he incluido en la declaración del procedimiento como un parámetro de salida.

    Ahora, la función «ejecutarSentencia» se quedaría de la manera que te indico a continuación, teniendo presente que le tendrás que pasar los parámetros que espera el procedimiento almacenado, a excepción del parámetro de salida, que será el valor que devuelva la función:


    Public Function ejecutaSentencia(ByVal nomEmpresa As String, _
                                                   ByVal direccion As String, _
                                                   ByVal representante As String, _
                                                   ByVal contactoTI As String) As String

            'Se declara la transacción para futuro uso
            Dim transaccion As SqlClient.SqlTransaction = Nothing

            Try
                'Se declara e instancia el comando
                Dim cmdincluir As New SqlClient.SqlCommand

                ' Abrimos la conexión
                cnConexion.Open()

                'Se ilustra el manejo de transacciones, sin embargo para este caso no es estrictamente necesario
                'Se inicia la transacción
                transaccion = cnConexion.BeginTransaction

                ' Construimos los parámetros del procedimiento
                Dim par As New SqlParameter("@nomEmpresa", SqlDbType.VarChar, 15)
                par.Value = nomEmpresa
                cmdincluir.Parameters.Add(par)

                par = New SqlParameter("@direccion", SqlDbType.VarChar, 30)
                par.Value = direccion
                cmdincluir.Parameters.Add(par)

                par = New SqlParameter("@representante", SqlDbType.VarChar, 30)
                par.Value = representante
                cmdincluir.Parameters.Add(par)

                par = New SqlParameter("@contactoTI", SqlDbType.VarChar, 30)
                par.Value = contactoTI
                cmdincluir.Parameters.Add(par)

                ' Creamos el parámetro de salida
                par = New SqlParameter("@loc_idcliente", SqlDbType.Decimal)
                par.Direction = ParameterDirection.Output
                cmdincluir.Parameters.Add(par)

                'Construye el comando Insert
                With cmdincluir
                    .Connection = cnConexion
                    .CommandText = "SP_sc_TBLCLIENTE_INSERT"
                    .CommandType = CommandType.StoredProcedure
                    .Transaction = transaccion
                    .ExecuteNonQuery()
                End With

                'Si hay exito efectúa el commit
                transaccion.Commit()

                Return CStr(cmdincluir.Parameters("@loc_idcliente").Value)

            Catch excsql As SqlClient.SqlException
                'Si no hay exito se efectua el Rollback
                transaccion.Rollback()
                MessageBox.Show("Error (" & excsql.Number.ToString & "): " & excsql.Message, "Error de Inclusion", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)

            Catch excgrl As Exception
                'Si no hay exito se efectúa el RollBack
                transaccion.Rollback()
                MessageBox.Show(excgrl.Message, "Error General", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)

            End Try

        End Function

    A la función la llamarías de la siguiente manera:

      ' Definimos la cadena de conexión
      '
      cnConexion = New SqlConnection("Data Source=(local);Initial Catalog=Base_Datos;Integrated Security=SSPI")

      Dim idcliente As String = ejecutaSentencia( _
                                              "valor_nombreEmpresa", _
                                              "valor_direccion", _
                                              "valor_representante", _
                                              "valor_contactoTI")

      MessageBox.Show(idcliente)

    ¡Eso es todo!

    Un saludo


    Enrique Martínez [MS MVP - VB]
    martes, 2 de junio de 2009 17:23
    Moderador
  • GRACIAS SoftJaén por responder...

    tengo un problema...
    la funcion "ejecuta sentencia" no la puedo variar como me indicas dado q es una funcion utilizada por toda la aplicacion.

    Ya modifique el SP pero aun continuo sin poder leer el valor devuelto.
    martes, 2 de junio de 2009 18:19
  • Y continuarás sin poder leer el valor devuelto por el procedimiento almacenado HASTA QUE NO MODIFIQUES LA FUNCIÓN "Ejecuta Sentencia", porque para poder obtener el valor, necesitas utilizar un objeto «SQLPARAMETER» con una dirección de salida (OUTPUT), tal y como te he indicado en el ejemplo.

    Debes de tener en cuenta que en Visual Basic se permite la sobrecarga de métodos, por lo que, aparte de tener tu propia función "Ejecuta Sentencia", tal cual la tienes definida, puedes añadir otra función con el mismo nombre, pero con distinto número de parámetros, es decir, la función que te he indicado anteriormente:

    Public Overloads Function ejecutaSentencia(ByVal pStrSQL As String) As String

       ' Tu función original 

    End Function


    Public Overloads Function ejecutaSentencia(ByVal nomEmpresa As String, _
                                                                   ByVal direccion As String, _
                                                                   ByVal representante As String, _
                                                                   ByVal contactoTI As String) As String

        ' La función sobrecargada

    End Function

    Si solamente llamas a la función utilizando un parámetro String, se ejecutará la primera sobrecarga de la función (tu función original), y si pasas cuatro parámetros del tipo String, se utilizará la segunda sobrecarga (la que yo te he indicado).


    Enrique Martínez [MS MVP - VB]
    martes, 2 de junio de 2009 18:59
    Moderador
  • mmm... ya veo....

    Pero no por el diseño q he estado llevando quisiera evitar modificar tanto la funcion.

    mmmm.. voy a seguir tratando.

    si logro algo te aviso.

    Gracias por su tiempo. De verdad se le agradece.
    martes, 2 de junio de 2009 19:56
  • buenas softJaen...

    Continué buscando y me encontre q lo podia hacer de la siguiente manera:

    1. al SP le puse un "return" al final para q me retorne el valor deseado.
    2. en el codigo, en lugar de llamar a "ejecutaSentencia()" lo que hago es abrir un dataset.
    	dsDato = modPrincipal.abreDataSet(strSQL)
    	insertData = dsDato.Tables(0).Rows(0).Item("ID_CLIENTE").ToString
    Haciendo esto, abro el dataset con el valor q me retorna el SP (el codigo correspondiente a la llamada en esta en la variable strSQL) y se lo asigno a una variable de tipo string y ya lo demas es conocido.

    Agradezco muchisimo su ayuda y el tiempo q dedico a ayudarme.

    salu2
    • Marcado como respuesta waraltca martes, 9 de junio de 2009 14:33
    martes, 9 de junio de 2009 14:33