Principales respuestas
Consulta mediante SP a SQL

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.
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- Marcado como respuesta Pedro AlfaroModerator miércoles, 16 de enero de 2019 19:14
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#.
- Propuesto como respuesta Pedro AlfaroModerator viernes, 28 de diciembre de 2018 20:14
-
-
-
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
-
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
-
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
-
-
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
-
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.
- Propuesto como respuesta Pedro AlfaroModerator miércoles, 2 de enero de 2019 18:04
-
Hola Alberto Feliz año nuevo
Bueno así es como me queda te parece bien la sintaxis y la estructura?
Function ValidacionRFID(ByVal TxbVALIDACION As Integer, ByVal TxbIDRFID As String, ByVal TxbIPMODULOConsulta As String) As Boolean
te recuerdo que esta en una capa de conexión para la cual uso una clase
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 -
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).
-
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 Suben 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 Tryme podrias orientar donde debo hacer la correcion para que pueda recibir el valor entero????????
Desde ya MIL GRACIAS Y DISCULPA LAS MOLESTIAS -
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.
- Editado Alberto PoblacionMVP miércoles, 9 de enero de 2019 18:02
-
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,
-
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) -
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(...).
-
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- Marcado como respuesta Pedro AlfaroModerator miércoles, 16 de enero de 2019 19:14