none
No toma el valor de un parametro(@valor) para una consulta sql RRS feed

  • 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")


    lunes, 7 de octubre de 2019 16:44

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
    lunes, 7 de octubre de 2019 19:05
  • 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
    martes, 8 de octubre de 2019 15:35

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
    lunes, 7 de octubre de 2019 19:05
  • 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
    martes, 8 de octubre de 2019 0:26
  • ¿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.

    martes, 8 de octubre de 2019 6:40
  • ¿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.

    Nunca he puesto el @ dentro de la sentencia, pero bueno probare si ese es el problema, por otro lado disculpa mi ignorancia pero nose como hacer un punto d ruptura para poder ver la colección de Parameters específicamente(lo he intentado por cierto)
    martes, 8 de octubre de 2019 10:52
  • 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.
    martes, 8 de octubre de 2019 11:33
  • 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
    martes, 8 de octubre de 2019 11:50
  • 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
    martes, 8 de octubre de 2019 15:35
  • Muchas gracias, quedo clarisimo
    miércoles, 9 de octubre de 2019 13:24