Principales respuestas
No toma el valor de un parametro(@valor) para una consulta sql

Pregunta
-
paso a comentar, tengo un procedimiento que genera dos tipos de consultas sql dinamicas, un select case que puede generar un insert o un update, en el insert todos los valores que paso mediante comandos.parameters.addwithvalue(@vbalor,texbox.text) funcionan bien, mi problema esta en el update, todos los valores pasados mediante parametros funcionan exepto luego del WHERE o sea en el id del registro q quiero modificar, paso el codigo completo y el fragmento donde paso los valores al procedimiento
Public Sub ConsultaSQL(tabla As String, arraycampos As String(), controles As Object(), checkbox As CheckBox(), consulta As String) Select Case consulta Case Is = "insert" Dim comandos As New OleDbCommand conexion.Open() Dim value As String = "" Dim cant As Integer = controles.Count Dim cant2 As Integer = checkbox.Count Dim cant3 As Integer = arraycampos.Count Dim campos As String = "" For i = 0 To cant3 - 1 If i = 0 Then campos = "" + campos + "" + arraycampos(i) + "" Else campos = "" + campos + "," + arraycampos(i) + "" End If Next MsgBox(campos) For i = 0 To cant - 1 If i = 0 Then value = "@valor0" Else If controles(i).text = "" Then value = "" + value + ",NULL" Else value = "" + value + ",@valor" & i & "" If i = cant - 1 Then For j = 0 To cant2 - 1 value = "" + value + ",@valor" & i + (j + 1) & "" Next End If End If End If Next MsgBox(value) Try comandos = New OleDbCommand("INSERT INTO " & tabla & " (" & campos & ")" & Chr(13) & "VALUES( " & value & ")", conexion) For i = 0 To cant - 1 If controles(i).text <> "" Then comandos.Parameters.AddWithValue("@valor" & i & "", controles(i).Text) End If If i = cant - 1 Then For j = 0 To cant2 - 1 comandos.Parameters.AddWithValue("@valor" & i + (j + 1) & "", checkbox(j).Checked) Next End If Next comandos.ExecuteNonQuery() MsgBox("Su nuevo registro ha sido guardado", vbInformation, "CORRECTO") conexion.Close() Catch ex As Exception MessageBox.Show(ex.Message) ' MsgBox("ERROR AL GUARDAR", vbCritical, "ATENCION") conexion.Close() End Try Case Is = "update" Dim comandos As New OleDbCommand conexion.Open() Dim value As String = "" Dim cant As Integer = controles.Count Dim cant2 As Integer = checkbox.Count Dim cant3 As Integer = arraycampos.Count Dim camposyVal As String = "" Dim campoWhere As String = "" For i = 0 To cant3 - 1 If i = 0 Then campoWhere = "" + arraycampos(i) + "= valor0" Else If i = 1 Then If controles(i).text = "" Then camposyVal = "" + arraycampos(i) + "= NULL" Else camposyVal = "" + arraycampos(i) + "= valor" & i & "" End If Else If i < cant Then If controles(i).text = "" Then camposyVal = "" + camposyVal + ", " + arraycampos(i) + "= NULL" Else camposyVal = "" + camposyVal + ", " + arraycampos(i) + "= valor" & i & "" End If Else camposyVal = "" + camposyVal + ", " + arraycampos(i) + "= valor" & i & "" End If End If End If Next MsgBox(camposyVal) Try comandos = New OleDbCommand(" UPDATE " & tabla & " SET " & camposyVal & " WHERE " & campoWhere & "", conexion) 'MsgBox(" UPDATE " & tabla & " SET " & camposyVal & " WHERE " & campoWhere & "") For i = 0 To cant - 1 If i = 0 Then comandos.Parameters.AddWithValue("@valor" & i & "", Convert.ToString(controles(i).Text)) Else If controles(i).text <> "" Then comandos.Parameters.AddWithValue("@valor" & i & "", controles(i).Text) End If If i = cant - 1 Then For j = 0 To cant2 - 1 comandos.Parameters.AddWithValue("@valor" & i + (j + 1) & "", checkbox(j).Checked) Next End If End If Next comandos.ExecuteNonQuery() MsgBox("Su nuevo registro ha sido guardado", vbInformation, "CORRECTO") conexion.Close() Catch ex As Exception MessageBox.Show(ex.Message) ' MsgBox("ERROR AL GUARDAR", vbCritical, "ATENCION") conexion.Close() End Try End Select End Sub
he hecho unas pruebas y si en lugar de colocar un parametro "valor0" a la variable campoWhere, le colocara algo estatico como en este ejemplo a continuacion entonces si funciona d maravilla pero la idea es que sea dinamico, aclaro que ya probe convertir de 3 formas distintas a string el parametro pero sigue sin funcionar
For i = 0 To cant3 - 1 If i = 0 Then campoWhere = "" + arraycampos(i) + "= 777" Else 'como aclare, aca paso un valor estatico y entonces el update funciona de maravilla pero la idea no es q sea estatico
aca muestro a modo de ejemplo los valores q paso para el procedimiento
ElseIf Button3.Text = "Guardar" Then Dim SQLControles = {TextBox8, TextBox1, ComboBox2, DateTimePicker1} Dim SQLCheckbox = {CheckBox380} Dim campos = {"id", "dpto", "localidad", "fecRecep", "reposOrig"} ConsultaSQL("vivienda", campos, SQLControles, SQLCheckbox, "update")
Respuestas
-
Creo que el problema ocurre debido a que estás usando un OleDbCommand pero estás pasando los parámetros al estilo del SqlCommand. Con el SqlCommand lo que importa es el nombre de los parámetros y los puedes pasar en cualquier orden, e incluso usar un mismo parámetro más de una vez en la misma sentencia. Pero con OleDb, dependiendo de cuál sea el driver que estás usando, falla si no le pasas los parámetros en el mismo orden en el que se usan en la sentencia. Es decir, si lo primero le pasas un parámetro que se llama @Valor0 pero luego lo usas al final de todo en el Where, no lo toma correctamente. Esto sí que funciona con el SqlCommand, pero ya te digo que con ciertos drivers de OleDb da problemas. Prueba a pasarle los parámetros en el mismo orden en que los usa, a ver si funciona.
Por cierto, tienes un error donde pones la condición "=NULL". Eso siempre devuelve "false". Ningún valor es nunca igual a NULL, ni siquiera dos NULL son iguales entre sí. En su lugar tienes que poner "IS NULL".
- Marcado como respuesta Ultimatux martes, 8 de octubre de 2019 11:54
-
No, el IS NULL solo es para las comparaciones, no para las asignaciones. Las asignaciones se hacen con =NULL.
En otras palabras, en el WHERE se pone IS NULL, pero en el SET se pone =NULL.
- Marcado como respuesta Ultimatux miércoles, 9 de octubre de 2019 13:23
Todas las respuestas
-
Creo que el problema ocurre debido a que estás usando un OleDbCommand pero estás pasando los parámetros al estilo del SqlCommand. Con el SqlCommand lo que importa es el nombre de los parámetros y los puedes pasar en cualquier orden, e incluso usar un mismo parámetro más de una vez en la misma sentencia. Pero con OleDb, dependiendo de cuál sea el driver que estás usando, falla si no le pasas los parámetros en el mismo orden en el que se usan en la sentencia. Es decir, si lo primero le pasas un parámetro que se llama @Valor0 pero luego lo usas al final de todo en el Where, no lo toma correctamente. Esto sí que funciona con el SqlCommand, pero ya te digo que con ciertos drivers de OleDb da problemas. Prueba a pasarle los parámetros en el mismo orden en que los usa, a ver si funciona.
Por cierto, tienes un error donde pones la condición "=NULL". Eso siempre devuelve "false". Ningún valor es nunca igual a NULL, ni siquiera dos NULL son iguales entre sí. En su lugar tienes que poner "IS NULL".
- Marcado como respuesta Ultimatux martes, 8 de octubre de 2019 11:54
-
Creo que el problema ocurre debido a que estás usando un OleDbCommand pero estás pasando los parámetros al estilo del SqlCommand. Con el SqlCommand lo que importa es el nombre de los parámetros y los puedes pasar en cualquier orden, e incluso usar un mismo parámetro más de una vez en la misma sentencia. Pero con OleDb, dependiendo de cuál sea el driver que estás usando, falla si no le pasas los parámetros en el mismo orden en el que se usan en la sentencia. Es decir, si lo primero le pasas un parámetro que se llama @Valor0 pero luego lo usas al final de todo en el Where, no lo toma correctamente. Esto sí que funciona con el SqlCommand, pero ya te digo que con ciertos drivers de OleDb da problemas. Prueba a pasarle los parámetros en el mismo orden en que los usa, a ver si funciona.
Por cierto, tienes un error donde pones la condición "=NULL". Eso siempre devuelve "false". Ningún valor es nunca igual a NULL, ni siquiera dos NULL son iguales entre sí. En su lugar tienes que poner "IS NULL".
he probado lo que me recomendaste pero sigue sin tomar el valor del parametro pasado pero si yo por ejemplo reemplazo "arraycampo(i)" por un valor estatico "777" o bien capturando el dato de un textbox.text, alli si funciona y la verdad que nose como proseguir porque en teoria deberia estar bien esto..
adjunto una imagen donde se ve claramente que el valor del id= valor5 es el ultimo de la cadena como bien me lo comentaste
Por cierto gracias por lo del NULL, no me había percatado del error- Editado Ultimatux martes, 8 de octubre de 2019 2:32
-
¿No les falta la @ a los parámetros en la sentencia?
Otra cosa que puedes probar es poner un punto de ruptura justo antes del ExecuteNonQuery y cuando pare ahí, usar el debugger para examinar la colección de Parameters, a ver si todo le ha llegado como se esperaba y en el orden correcto.
-
¿No les falta la @ a los parámetros en la sentencia?
Otra cosa que puedes probar es poner un punto de ruptura justo antes del ExecuteNonQuery y cuando pare ahí, usar el debugger para examinar la colección de Parameters, a ver si todo le ha llegado como se esperaba y en el orden correcto.
-
nose como hacer un punto d ruptura
Desde Visual Studio, basta con que pongas el cursor en la linea deseada y pulses F9. Entonces la linea se pone de color rojo para indicar que se va a parar en esa linea. Ejecutas el programa con la F5 ("iniciar con depuracion") y al llegar a la linea marcada se para ahi y puedes examinar todas las variables. -
nose como hacer un punto d ruptura Desde Visual Studio, basta con que pongas el cursor en la linea deseada y pulses F9. Entonces la linea se pone de color rojo para indicar que se va a parar en esa linea. Ejecutas el programa con la F5 ("iniciar con depuracion") y al llegar a la linea marcada se para ahi y puedes examinar todas las variables.
eso si, pense que se podia ver especificamente el valor dentro de la variable @valor, igualmente te comento que ahora si lo hice funcionar, acomode mejor las ubicaciones y entendí que los valores son pasados como referencia como cualqier procedimiento, asi que muchas gracias por la ayuda aunque ahora me tira error de sintaxis desde que cambie el "= NULL" por el "IS NULL", muestro la captura de la sentencia para corroborar
en cambio volvi a colocar " = NULL " y en ese caso si funciona correctamente de igual forma, lo posteo para saber tu opinion al respecto, porque he leido en foros que algunos dicen que se coloca "IS NULL" y otros "= NULL" mis conocimientos en sql son de termino medio bajo por eso no estoy muy seguro- Editado Ultimatux martes, 8 de octubre de 2019 11:58
-
No, el IS NULL solo es para las comparaciones, no para las asignaciones. Las asignaciones se hacen con =NULL.
En otras palabras, en el WHERE se pone IS NULL, pero en el SET se pone =NULL.
- Marcado como respuesta Ultimatux miércoles, 9 de octubre de 2019 13:23
-