none
Consulta mediante SP a SQL RRS feed

  • Pregunta

  • Buenos días tengo este código en el que realizo una consulta a la base en SQL mediante un Procedimiento almacenado ya creado pero el código este esta hecho en C# quisiera si me pueden ayudar como hacerlo para ASP.NET.vb

    cmd . CommantType = CommandType . StoredProcedure ; 
    cmd . CommandText = "dbo.ARDUINO_Validar_Credencial" ; 
    cmd . Parámetros . Añadir ( "@IDRFID" , SqlDbType . NVarChar , 50 ). Valor = "28368571" ; 
    cmd . Parámetros . Añadir ( "@IP" , SqlDbType . NVarChar , 50 ). Valor = "192.168.0.11" ; 
    cmd . Parámetros . add ( "@retorno" , SqlDbType . Int ). ParameterDirection = ParameterDirection . Salida ;   
    cmd . ExecuteNonQuery ();
    total = ( Int ) cmd . Parámetros [ "@retorno" ]. Valor ; 

    básicamente lo que necesito que haga es: ingreso dos valores IDRFID y IP y si se verifica que están vinculados me devuelve un un valor 0 o 1.
    en el sql anda perfecto pero debo hacer la consulta desde el ASP.

       
    viernes, 28 de diciembre de 2018 15:25

Respuestas

  • Hola Alberto, Javi y Greg desde ya MIL GRACIAS POR TODA LA AYUDA ESTOS DIAS Y MIL DISCULPAS POR HABER ESTADO TAN MOLESTO.

    PUDE RESOLVERLO MODIFICANDO LA ESTRUCTURA DEL SP

    LES ADJUNTO TODO LOS PASOS. ESTO ES UN PROYECTO DONDE EL USUARIO SE CONECTA VIA LAN A  UNA TERMINAL DE ARDUINO AL ASP Y ESTE AL SQL Y LA RESPUESTA DETERMINA UNA ACCIÓN EN EL ARDUINO 

    PROCEDIMIENTO ALMACENADO (OBJETIVO INGRESAR 2 PARAMETROS E IDENTIFICAR SI ESTAN DADOS DE ALTA Y SI SE ENCUENTRAN VINCULADOS)
    USE [TesisSaer]
    GO
    /****** Object:  StoredProcedure [dbo].[ARDUINO_Validar_Credencial]    Script Date: 10/01/2019 17:44:40 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER Procedure [dbo].[ARDUINO_Validar_Credencial]
    @IDRFID as nvarchar(50),
    @IP as nvarchar (50)
    as
     select  COUNT(IP)as Validacion from tb_modulos as TBMO inner join tb_usuarios as TBUS on TBMO.oficina = TBUS.oficina 
                                                                 inner join tb_credencial as TBCRE on TBUS.DNI = TBCRE.DNI 
                        
      where TBCRE.IDRFID = @IDRFID AND TBMO.IP = @IP

    execute ARDUINO_Validar_Credencial "id","ip"
    Validacion
    1 - 0
     Codigo Capa logica VB.NET (lo aplique a un boton como medio de prueba pero puede ir en el Load)
      Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            cn.ValidacionRFID(TxbIDRFID.Text, TxbIPMODULOConsulta.Text, TxbVALIDACION) --> toma los valores de los TEXTBOX y los pasa a la  capa conexion -->SU ValidacionRFID


    Codigo capa Conexion VB.NET

     Sub ValidacionRFID(ByVal TxbIDRFID As String, ByVal TxbIPMODULOConsulta As String, ByVal TxbVALIDACION As TextBox)
            Try
                cmd = New SqlCommand("ARDUINO_Validar_Credencial", cn)
                cmd.CommandType = CommandType.StoredProcedure
                With cmd.Parameters
                    .AddWithValue("@IDRFID", TxbIDRFID)
                    .AddWithValue("@IP", TxbIPMODULOConsulta)
                End With
                dr = cmd.ExecuteReader
                If dr.Read Then
                    TxbVALIDACION.Text = dr.Item("Validacion")
                End If
                dr.Close()
            Catch ex As Exception
                MsgBox("Error al traer valor" + ex.ToString)
            End Try
        End Sub

     MUCHAS GRACIAS 
    jueves, 10 de enero de 2019 20:41

Todas las respuestas

  • Esencialmente el código en VB es prácticamente idéntico, salvo que hay que quitar los puntos y comas del final, y los paréntesis cuadrados tienen que ser redondos. Quita el (int) de la última sentencia.

    Ah, y me imagino que esto será completamente evidente y ya te habrás dado cuenta: Todas las palabras clave que has puesto en español tienen que ir en inglés (por ejemplo Add en lugar de Añadir, Value en lugar de Valor, etc.). Pero esto no es debido a que lo estés pasando de C# a VB, las palabras clave siempre tienen que ir en inglés, tanto en VB como en C#.

    viernes, 28 de diciembre de 2018 15:55
  • muchas gracias ya lo reviso y comento como me fue.
    viernes, 28 de diciembre de 2018 21:18
  • consulta como manejo la variable que me devuelve el SP llegue hasta ahi y se me quemaron los libros 
    viernes, 28 de diciembre de 2018 21:48
  • llegue a esto 

        Function ValidacionRFID(ByVal TxbVALIDACION As Integer, ByVal TxbIDRFID As String, ByVal TxbIPMODULOConsulta As String) As Boolean
            Try
                cmd = New SqlCommand("ARDUINO_Validar_Credencial", cn)
                cmd.CommandType = CommandType.StoredProcedure

                With cmd.Parameters
                    .AddWithValue("@IDRFID", TxbIDRFID)
                    .AddWithValue("@IP", TxbIPMODULOConsulta)

                    .AddWithValue("@retorno", SqlDbType.Int).Direction = ParameterDirection.Output

                End With
                da = New SqlDataAdapter
                da.SelectCommand = cmd
                dt = New DataTable
                da.Fill(dt)

                cmd.ExecuteNonQuery()
                total = Int() cmd.Parameters("@retorno"). Valor  


    • Editado AlexWirtzW viernes, 28 de diciembre de 2018 21:55 faltaban datos
    viernes, 28 de diciembre de 2018 21:54

  • básicamente lo que necesito que haga es: ingreso dos valores IDRFID y IP y si se verifica que están vinculados me devuelve un un valor 0 o 1.
    en el sql anda perfecto pero debo hacer la consulta desde el ASP.

       

    al convertir el codigo a vb puedes utilizar http://converter.telerik.com/

    Public Sub ConsultarRFDI()
        cmd.CommantType = CommandType.StoredProcedure
        cmd.CommandText = "dbo.ARDUINO_Validar_Credencial"
        cmd.Parameters.Add("@IDRFID", SqlDbType.NVarChar, 50).Value = "28368571"
        cmd.Parameters.Add("@IP", SqlDbType.NVarChar, 50).Value = "192.168.0.11"
        cmd.Parameters.add("@return", SqlDbType.Int).ParameterDirection = ParameterDirection.Out
        cmd.ExecuteNonQuery()
        total = CType(cmd.Parámetros("@return").Value, Int)
    End Sub

    lo otro es como tienes configurado tu SP 

    creo que debes tener algo asi...

    @User int OUTPUT
    
    SELECT IDRFID, IP FROM Credenciales c WHERE c.IDRFID = @IDRFID AND c.IP = @IP;
    
    IF @@ROWCOUNT > 0
       User = 1
    ELSE
      User = 0

    viernes, 28 de diciembre de 2018 22:11
  • asi tengo el SP en el SQL

    create Procedure ARDUINO_Validar_Credencial
    @IDRFID as nvarchar(50),
    @IP as nvarchar (50),
    @RETORNO int output
    as
     
    set  @RETORNO  = ( select  COUNT(IP) from tb_modulos as TBMO inner join tb_usuarios as TBUS on TBMO.oficina = TBUS.oficina 
                                                                 inner join tb_credencial as TBCRE on TBUS.DNI = TBCRE.DNI 
                        
      where TBCRE.IDRFID = @IDRFID AND TBMO.IP = @IP)


    • Editado AlexWirtzW viernes, 28 de diciembre de 2018 22:20 corrección de datos
    viernes, 28 de diciembre de 2018 22:17
  • ocurre que lo trabajo como una funcion porque trabajo en capas y este codigo que imboca el sp esta en la capa de conexion 
    viernes, 28 de diciembre de 2018 22:19
  • Hola AlexWirtzW:

    Y porque no utilizas executeScalar, dado que lo que quieres retornar es un valor único.

    Dim n as Integer
    n = CInt(cmd.ExecuteScalar())

    Procedure

    create Procedure ARDUINO_Validar_Credencial (
    @IDRFID as nvarchar(50),
    @IP as nvarchar (50),
    @RETORNO int )
    as
    begin 
    select  COUNT(IP) from tb_modulos as TBMO inner join tb_usuarios as TBUS on TBMO.oficina = TBUS.oficina 
                                                                 inner join tb_credencial as TBCRE on TBUS.DNI = TBCRE.DNI 
                        
      where TBCRE.IDRFID = @IDRFID AND TBMO.IP = @IP
    return

    ExecuteScalar

    https://docs.microsoft.com/es-es/dotnet/api/system.data.sqlclient.sqlcommand.executescalar?view=netframework-4.7.2

    sábado, 29 de diciembre de 2018 7:08
  • llegue a esto 

    [...]

    Bien, eso está casi bien, pero veo un par de fallos:

    Uno que que primero estás usando un "Fill" para llenar un datatable. Eso no sirve para nada, primero porque tu procedimiento no devuelve ningún registro para la tabla, y segundo porque incluso aunque los devolviese tu función no hace nada con el datatable y lo destruye inmediatamente antes de salir de la función. Asi que borra todo ese bloque que sobra.

    Lo segundo es que esta línea:

    total = Int() cmd.Parameters("@retorno"). Valor  

    debería ser así:

    total = cmd.Parameters("@retorno").Value

    Fíjate que habías vuelto a cometer otra vez el error de poner Valor en lugar de Value. Y el int() probablemente pretendía ser un "cast" traducido desde C#. En VB no se usa esa construcción; hay que usar la función CType o DirectCast si realmente necesitas hacer la conversión, pero de forma predeterminada y mientras no lo desactives con un Option Strict, el VB te deja hacer las conversiones de tipos de manera implícita, sin que tengas que escribir nada para hacer el cast.

    sábado, 29 de diciembre de 2018 8:50
  • Hola Alberto Feliz año nuevo 

    Bueno así es como me queda te parece bien la sintaxis y la estructura? 
    te recuerdo que esta en una capa de conexión para la cual uso una clase 

     Function ValidacionRFID(ByVal TxbVALIDACION As Integer, ByVal TxbIDRFID As String, ByVal TxbIPMODULOConsulta As String) As Boolean
            Try
                cmd = New SqlCommand("ARDUINO_Validar_Credencial", cn)
                cmd.CommandType = CommandType.StoredProcedure

                With cmd.Parameters
                    .AddWithValue("@IDRFID", TxbIDRFID)
                    .AddWithValue("@IP", TxbIPMODULOConsulta)

                    .AddWithValue("@retorno", SqlDbType.Int).Direction = ParameterDirection.Output

                End With
                cmd.ExecuteNonQuery()
                total = cmd.Parameters("@retorno").Value

            Catch ex As Exception
            End Try
            Return total
            TxbVALIDACION = total
        End Function

    jueves, 3 de enero de 2019 19:43
  •  así es como me queda te parece bien la sintaxis y la estructura? 

    Está más o menos bien, pero hay algunas cosillas que pulir:

    Primero, la función tiene un "Return total" y después de esa sentencia hay otra. Esa otra no se ejecutará nunca, porque al llegar al return se abandona la función. Así que puedes suprimirla, ya que nunca se ejecutará.

    La función es de tipo "Boolean". Y haces un "return total" siendo "total" el valor devuelto por el parámetro de salida. Y ese parámetro lo has definido como "Int" en lugar de "Boolean". Aunque el VB intentará hacer de manera implícita una conversión de Int a Boolean, los valores del Int devueltos por tu procedimiento (0 y 1) no coindicen con los valores de Boolean usados por VB (0 y -1). Esto puede dar lugar a que no se retorne correctamente el valor que esperabas. Acostúmbrate a no mezclar tipos de datos distintos y hacer conversiones implícitas entre ellos, porque a la larga acaban introduciendo errores que no se detectan en tiempo de compilación pero que luego fallan al ejecutar el programa. En este caso particular la solución es usar SqlDbType.Bit en lugar de SqlDbType.Int para el parámetro, pero con carácter general cuando programaes fíjate bien en los tipos de datos que usas y cerciórate de que son coherentes, no asgnes a lo loco cualquier variable a cualquier otra sin preocuparte del tipo que tienen.

    Finalmente, otra mala práctica: Tienes un bloque Catch vacío. Esto no dará ningún error al compilar, pero hará muy difícil detectar los problemas de funcionamiento cuando se produzca un error al llamar al procedimiento almacenado. Asegúrate de que tus "Catch" siempre hacen "algo", que puede ir desde grabar un Log hasta elevar el error a la capa superior para que ésta informe al usuario. Pero no los dejes nunca vacíos (salvo rarísimas excepciones que se deben documentar y justificar).

    viernes, 4 de enero de 2019 6:23
  • Buenos días Alberto bueno creo que hice las correcciones que me recomendaste pero ahora me surge un problemita nuevo.

    Como dije anteriormente estoy trabajando en 2 capas de programación.
    En la primera:

    Public Class _Interface
        Inherits System.Web.UI.Page

        Public cn As New CONEXION_SQL

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            cn.conectarArduino_SQL()
            cn.insertarConsumo(TxbIPMODULOInsert.Text, TxbCONSUMOInsert.Text)
        End Sub

    Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            cn.ValidacionRFID(CInt(TxbVALIDACION.Text), TxbIDRFID.Text, TxbIPMODULOConsulta.Text)

        End Sub  

    en las lineas en negrita intento pasar y luego recibir el dato resultante de SP pero me dice que no es posible convertir la cadena STRING en un Entero (Entero 0 o 1 que me devuelve la función que invoca al SP)

    CAPA DE CONEXION A LA BASE DE DATOS 

    Sub ValidacionRFID(ByVal TxbVALIDACION As Integer, ByVal TxbIDRFID As String, ByVal TxbIPMODULOConsulta As String)
            Dim salida As String = ""
            Try
                cmd = New SqlCommand("dbo.ARDUINO_Validar_Credencial", cn)
                cmd.CommandType = CommandType.StoredProcedure

                With cmd.Parameters
                    .AddWithValue("@IDRFID", TxbIDRFID)
                    .AddWithValue("@IP", TxbIPMODULOConsulta)

                    .AddWithValue("@retorno", TxbVALIDACION)
                End With
                cmd.ExecuteNonQuery()
                'Dim total As Integer

                TxbVALIDACION = (CInt("@retorno"))
            Catch ex As Exception
            End Try

    me podrias orientar donde debo hacer la correcion para que pueda recibir el valor entero???????? 
    Desde ya MIL GRACIAS Y DISCULPA LAS MOLESTIAS 

       
    miércoles, 9 de enero de 2019 15:13
  •  no es posible convertir la cadena STRING en un Entero

    Casi seguro que un error se produce en esta línea:

    TxbVALIDACION = (CInt("@retorno"))

    Fíjate que estás intentando hacer un CInt del texto "@retorno". Insisto en que es un texto, escrito entre comillas. El hecho de que casualmente en tu procedimiento exista un parámetro de SQL que también tenga el mismo nombre "@retorno" es irrelevante para la función CInt. Esta función no sabe nada acerca de parámetros SQL. Lo único que "ve" es que le has pasado un texto que no es un número entero, y por lo tanto da un error.

    Conclusión: Primero tienes que recuperar el valor del parámetro, antes de pasárselo al CInt. Y tal como tienes el código, no se puede recuperar ese valor porque el parámetro es solo de entrada. Sí, en el procedimiento almacenado es de salida, pero en tu código cliente has usado AddWithValue, y eso siempre lo define como entrada, así que no puede funcionar.

    Pero no son esos dos los únicos errores que tienes.

    Otro error es que asignas un valor a la variable TxbVALIDACION, pero esa variable es solo de entrada (pasa por valor dado que no has puesto ByRef), por lo que no puede "salir" de la subrutina.

    Después otro problema es que en la llamada al método estás pasando TxbVALIDACION.Text, es más lo estás convirtiendo a entero. ¿Qué es TxbVALIDACION? ¿Contiene un entero en el momento de hacer la llamada? Si no lo contiene, ahí dará otro error. Y desde luego, tal como está no pude recibir un valor de vuelta desde la subrutina.

    Por cierto, es bastante mala costumbre llamar con el mismo nombre a dos variables que no tienen nada que ver una con la otra, porque induce a confusión al leer el programa. En particular, la variable TxbVALIDACION que usas en la subrutina es un número entero, mientras que la variable TxbVALIDACION que hay en el Button1_Click no se sabe lo que es pero presumiblemente debe ser un TextBox o algo por el estilo, porque sino no tendría una propiedad .Text.


    miércoles, 9 de enero de 2019 18:00
  • Hola 
    La variable TxbVALIDACION.text es un Text Box. donde lo que deberia estar haciendo es recibir un valor entero 0 o 1 que trae el parametro @retorno procedente del SP en el SQL. 
    como llego a intentar obtenerlo?
    primero en dos Text Box (tbsIDRFID.Text y el TbxIPVALIDACION.text) los uso para intentar enviar al procedimiento almacenado dos parametros una IP y un id ambos en formato string. y el SP en el SQL si verifica que estos estan vinculados entre si me devuelve un 1 si no un 0 estes 1 o 0 son los que debo cargar en el TbxVALIDACION,
      
    miércoles, 9 de enero de 2019 21:56
  • este es el procedimiento almacenado que uso el cual recibiria dos parametros el IDRFID e IP  y deberia devolver @RETORNO (0 - 1)

    USE [TesisSaer]
    GO
    /****** Object:  StoredProcedure [dbo].[ARDUINO_Validar_Credencial]    Script Date: 09/01/2019 19:34:00 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER Procedure [dbo].[ARDUINO_Validar_Credencial]
    @IDRFID as nvarchar(50),
    @IP as nvarchar (50),
    @RETORNO int output
    as

    set  @RETORNO  = ( select  COUNT(IP) from tb_modulos as TBMO inner join tb_usuarios as TBUS on TBMO.oficina = TBUS.oficina 
                                                                 inner join tb_credencial as TBCRE on TBUS.DNI = TBCRE.DNI 

      where TBCRE.IDRFID = @IDRFID AND TBMO.IP = @IP)

                         
    miércoles, 9 de enero de 2019 22:21
  • Sí, el procedimiento está bien, y devuelve correctamente el parámetro @retorno que está marcado como "output". El problema está en el código que hace la llamada al procedimiento, donde has creado el parámetro con ".AddWithValue", y eso lo declara de tipo "input", no de tipo "output", por lo que no es capaz de recoger el valor devuelto. Para poder declarar el parámetro output, tienes que renunciar al método abreviado .AddWithValue y en su lugar usar el método largo .Parameters.Add y ponerle la propiedad ParameterDirection.Output. Ya te ha puesto greg_dorian un ejemplo de cómo se hace esto.

    Y recuerda que sigue habiendo otro problema en tu "Sub": Si quieres devolver el resultado a través del argumento de la subrutina, hay que declararlo como "ByRef" en lugar de "ByVal". Eso ocasionará otro error en el código llamante porque no puedes pasar una expresión a un ByRef, tendrás que usar una variable en lugar de la expresión CInt(...).

    jueves, 10 de enero de 2019 8:02
  • Hola Alberto, Javi y Greg desde ya MIL GRACIAS POR TODA LA AYUDA ESTOS DIAS Y MIL DISCULPAS POR HABER ESTADO TAN MOLESTO.

    PUDE RESOLVERLO MODIFICANDO LA ESTRUCTURA DEL SP

    LES ADJUNTO TODO LOS PASOS. ESTO ES UN PROYECTO DONDE EL USUARIO SE CONECTA VIA LAN A  UNA TERMINAL DE ARDUINO AL ASP Y ESTE AL SQL Y LA RESPUESTA DETERMINA UNA ACCIÓN EN EL ARDUINO 

    PROCEDIMIENTO ALMACENADO (OBJETIVO INGRESAR 2 PARAMETROS E IDENTIFICAR SI ESTAN DADOS DE ALTA Y SI SE ENCUENTRAN VINCULADOS)
    USE [TesisSaer]
    GO
    /****** Object:  StoredProcedure [dbo].[ARDUINO_Validar_Credencial]    Script Date: 10/01/2019 17:44:40 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER Procedure [dbo].[ARDUINO_Validar_Credencial]
    @IDRFID as nvarchar(50),
    @IP as nvarchar (50)
    as
     select  COUNT(IP)as Validacion from tb_modulos as TBMO inner join tb_usuarios as TBUS on TBMO.oficina = TBUS.oficina 
                                                                 inner join tb_credencial as TBCRE on TBUS.DNI = TBCRE.DNI 
                        
      where TBCRE.IDRFID = @IDRFID AND TBMO.IP = @IP

    execute ARDUINO_Validar_Credencial "id","ip"
    Validacion
    1 - 0
     Codigo Capa logica VB.NET (lo aplique a un boton como medio de prueba pero puede ir en el Load)
      Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            cn.ValidacionRFID(TxbIDRFID.Text, TxbIPMODULOConsulta.Text, TxbVALIDACION) --> toma los valores de los TEXTBOX y los pasa a la  capa conexion -->SU ValidacionRFID


    Codigo capa Conexion VB.NET

     Sub ValidacionRFID(ByVal TxbIDRFID As String, ByVal TxbIPMODULOConsulta As String, ByVal TxbVALIDACION As TextBox)
            Try
                cmd = New SqlCommand("ARDUINO_Validar_Credencial", cn)
                cmd.CommandType = CommandType.StoredProcedure
                With cmd.Parameters
                    .AddWithValue("@IDRFID", TxbIDRFID)
                    .AddWithValue("@IP", TxbIPMODULOConsulta)
                End With
                dr = cmd.ExecuteReader
                If dr.Read Then
                    TxbVALIDACION.Text = dr.Item("Validacion")
                End If
                dr.Close()
            Catch ex As Exception
                MsgBox("Error al traer valor" + ex.ToString)
            End Try
        End Sub

     MUCHAS GRACIAS 
    jueves, 10 de enero de 2019 20:41