none
Error con tipo de parámetro. RRS feed

  • Pregunta

  • Hola a todos:

    Tengo la consulta de actualización de DatagridView en una tabla que funciona perfectamente, excepto cuando le quiero insertar un parámetro, me indica que tengo que indicar explícitamente el tipo de parámetro, pero no se como indicárselo utilizando DbFactory. He mirado por los foros y me hablan de colocar una extensión en el código donde declaro el prámetro y no lo acabo de entender.

    Este es mi procedimiento, en el cual me interesaría que ciertos valores los divida por la propiedad Varglobal.ValorDivisor y es ahí cuando me salta el error.

      Public Shared Function ActualizarDatosDatagridActivoNetoReal(codEmpresa As String, dt As DataTable) As Integer
    
            If (dt Is Nothing) Then
                Throw New ArgumentNullException("dt")
            End If
    
            ' Creamos el acceso a datos mediante el nombre de la cadena de conexión existente en el archivo de configuración de la aplicación.
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
    
            ' Declaramos una variable Connection
            Using cnn As DbConnection = da.CreateConnection()
    
                ' Creamos el Commando
                Dim cmd As DbCommand = cnn.CreateCommand()
    
                cnn.Open()
    
                ' Especificamos la consulta SQL de selección
                cmd.Parameters.Add(Configuracion.CreateParameter(cmd, "@divisor", VarGlobal.ValorDivisor))
    
                cmd.CommandText = "SELECT IdBalance, Cod_Empresa, Descripcion, (ValorContable / @divisor) as ValorContable, Amortizacion, Deterioro, ValorNeto, Plusvalia, Minusvalia, ValorReal " &
                                  "FROM BalSitExpl "
              
                ' Actualizamos el origen de datos devolviendo
                ' el número de registros afectados.
                '
                Return MetodosDatos.UpdateData(cmd, dt)
    
            End Using
    
        End Function

    Bueno al final la pregunta, es como le puedo indicar al parámetro que es del tipo double, he probado con DbType, etc. y me da error de demasiados argumentos.

    Bueno, muchas gracias a todos y un saludo.

    Gemma


    jueves, 2 de junio de 2016 6:26

Respuestas

  • "gemma_campillo" escribió:

    > He creado una función para extender la declaración del parámetro, pero continúa
    > dando el error en el momento de actualizar. "El método OleDbCommand.Prepare
    > requiere que todos los parámetros tengan un tipo establecido de forma explícita."
    >
    > Esto es lo que he hecho pero no se si está bien:
    >
    > Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String,
    >                     type As DbType, value As Object) As DbParameter
    >

    Tienes que asignarle el DbType pasado a la función a la propiedad DbType del objeto DbParameter creado en la función CreateParameterConTipo:

        Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String,
                        type As DbType, value As Object) As DbParameter
    
           If (cmd Is Nothing) Then
               Throw New ArgumentException("El valor del comando no es válido.")
           End If
    
           Dim param As DbParameter = cmd.CreateParameter()
           param.ParameterName = name
           param.Value = value
    
           ' Le asignamos el tipo de dato al parámetro
           param.DbType = type
    
           Return param
    
        End Function
    

    Y como comentas que el tipo de dato es Double, llamarías a la función de la siguiente manera:

        'Especificamos la consulta SQL de selección
        cmd.Parameters.Add(CreateParameterConTipo(cmd, "@divisor", DbType.Double, VarGlobal.ValorDivisor))

    Prueba de nuevo, pero no sé yo en estos momentos si te va a funcionar por el tipo de consulta SQL de selección con el que deseas configurar la propiedades InsertCommand, UpdateCommand y DeleteCommand de un adaptador de datos.

    Fíjate que estás seleccionando un campo calculado en la consulta SQL de selección:

       cmd.CommandText = "SELECT ..., (ValorContable / @divisor) as ValorContable, ...

    Y la verdad es que no sé si el objeto DbCommandBuilder va a ser capaz de construir las consultas de inserción, actualización y eliminación que necesita ejecutar el método Update del adaptador de datos.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta gemma_campillo jueves, 2 de junio de 2016 7:58
    jueves, 2 de junio de 2016 7:08
    Moderador
  • debes establecer el tipo dentro de tu nuevo metodo

    Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String, type As DbType, value As Object) As DbParameter
    
            If (cmd Is Nothing) Then
                Throw New ArgumentException("El valor del comando no es válido.")
            End If
    
            Dim param As DbParameter = cmd.CreateParameter()
            param.ParameterName = name
    param.DbType = type ' establecer el tipo
            param.Value = value
    
            Return param
    
        End Function
    
    
    


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    • Marcado como respuesta gemma_campillo jueves, 2 de junio de 2016 8:04
    jueves, 2 de junio de 2016 7:07
  • "gemma_campillo" escribió:

    > El objeto DbCommandBuilder ha sido capaz de construir correctamente las consultas.

    ¡Entonces se ha portado como un "hombretón"! ;-)

    Pensaba que el problema venía por el campo calculado que aparece en la consulta SQL de selección, pero por el resultado satisfactorio que has obtenido, parece ser que basta con asignarle explícitamente el tipo de dato al parámetro en cuestión.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta gemma_campillo jueves, 2 de junio de 2016 10:54
    jueves, 2 de junio de 2016 8:46
    Moderador

Todas las respuestas

  • Puedes poner la firma de el método Configuracion.CreateParameter()?? Tal vez debas sobrecargarlo y agregar como ultimo parámetro el DBType

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 2 de junio de 2016 6:39
  • Hola Sergio:

    He creado una función para extender la declaración del parámetro, pero continúa dando el error en el momento de actualizar. "El método OleDbCommand.Prepare requiere que todos los parámetros tengan un tipo establecido de forma explícita."

    Esto es lo que he hecho pero no se si está bien:

       Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String, type As DbType, value As Object) As DbParameter
    
            If (cmd Is Nothing) Then
                Throw New ArgumentException("El valor del comando no es válido.")
            End If
    
            Dim param As DbParameter = cmd.CreateParameter()
            param.ParameterName = name
            param.Value = value
    
            Return param
    
        End Function
    
    
    
        Public Shared Function ActualizarDatosDatagridActivoNetoReal(codEmpresa As String, dt As DataTable) As Integer
    
            If (dt Is Nothing) Then
                Throw New ArgumentNullException("dt")
            End If
    
            ' Creamos el acceso a datos mediante el nombre de la cadena de conexión existente en el archivo de configuración de la aplicación.
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
    
            ' Declaramos una variable Connection
            Using cnn As DbConnection = da.CreateConnection()
    
                ' Creamos el Commando
                Dim cmd As DbCommand = cnn.CreateCommand()
    
                cnn.Open()
    
                'Especificamos la consulta SQL de selección
                cmd.Parameters.Add(CreateParameterConTipo(cmd, "@divisor", DbType.Double, VarGlobal.ValorDivisor))
    
                cmd.CommandText = "SELECT IdBalance, Cod_Empresa, Descripcion, (ValorContable / @divisor) as ValorContable, Amortizacion, Deterioro, ValorNeto, Plusvalia, Minusvalia, ValorReal " &
                                  "FROM BalSitExpl "
              
                ' Actualizamos el origen de datos devolviendo
                ' el número de registros afectados.
                '
                Return MetodosDatos.UpdateData(cmd, dt)
    
            End Using
    
        End Function

    El método general que tengo para añadir los parámetros, es igual al de la función, pero sin el DbType.

    Public Shared Function CreateParameter(cmd As DbCommand, name As String, value As Object) As DbParameter
    
            If (cmd Is Nothing) Then
                Throw New ArgumentException("El valor del comando no es válido.")
            End If
    
            Dim param As DbParameter = cmd.CreateParameter()
            param.ParameterName = name
            param.Value = value
    
            Return param
    
    
        End Function

    Además, el tipo de parámetro solo me lo pide en esta actualización de Datagridview a Tabla.

     Public Shared Function UpdateData(selectCommand As DbCommand, dt As DataTable) As Integer
    
            If (selectCommand Is Nothing) Then _
                Throw New ArgumentNullException("selectCommand")
    
            If (dt Is Nothing) Then _
                Throw New ArgumentNullException("dt")
    
            'Creamos el acceso a datos mediante el nombre de la cadena de conexión existente en el archivo de configuración de la aplicación.
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
    
            ' Declaramos una variable Connection
            Using cnn As DbConnection = da.CreateConnection()
    
                ' Creamos el Commando
                'Dim cmd As DbCommand = cnn.CreateCommand
    
                cnn.Open()
    
                selectCommand.Connection = cnn
    
                ' Creamos el adaptador de datos.
                Dim adaptador As DbDataAdapter = da.CreateDataAdapter()
                adaptador.SelectCommand = selectCommand
    
                ' Agrega información sobre la clave principal para completar el esquema.
                adaptador.MissingSchemaAction = MissingSchemaAction.AddWithKey
    
                ' Creamos un objeto CommandBuilder par actualizar los datos
                Dim cmdBuilder As DbCommandBuilder = da.CreateCommandBuilder()
    
                ' Añadimos los caracteres para encerrar los nombres de los campos entre corchetes.
                cmdBuilder.QuotePrefix = "["
                cmdBuilder.QuoteSuffix = "]"
    
                ' Le asignamos el objeto DataAdapter creado anteriormente.
                cmdBuilder.DataAdapter = adaptador
    
                ' Configuramos la propiedad UpdateCommand del adaptador de datos.
                adaptador.UpdateCommand = cmdBuilder.GetUpdateCommand()
    
                '' Añadimos los caracteres para encerrar los nombres de los campos entre corchetes.
                'cmdBuilder.QuotePrefix = "["
                'cmdBuilder.QuoteSuffix = "]"
    
                With adaptador
                    '.InsertCommand = cb.GetInsertCommand()
                    .UpdateCommand = cmdBuilder.GetUpdateCommand()
                    '.DeleteCommand = cb.GetDeleteCommand()
                End With
    
                'Dim n As Integer = da.Update(dt)
                'MsgBox("Nº de registros afectados: " & n)
    
                ' Actualizamos el origen de datos.
                Return adaptador.Update(dt)
    
            End Using
    
        End Function

    El error salta en la propiedad Update del adaptador de datos.

    Bueno, muchas gracias como siempre y un abrazo.

    Gemma

    jueves, 2 de junio de 2016 6:51
  • debes establecer el tipo dentro de tu nuevo metodo

    Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String, type As DbType, value As Object) As DbParameter
    
            If (cmd Is Nothing) Then
                Throw New ArgumentException("El valor del comando no es válido.")
            End If
    
            Dim param As DbParameter = cmd.CreateParameter()
            param.ParameterName = name
    param.DbType = type ' establecer el tipo
            param.Value = value
    
            Return param
    
        End Function
    
    
    


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    • Marcado como respuesta gemma_campillo jueves, 2 de junio de 2016 8:04
    jueves, 2 de junio de 2016 7:07
  • "gemma_campillo" escribió:

    > He creado una función para extender la declaración del parámetro, pero continúa
    > dando el error en el momento de actualizar. "El método OleDbCommand.Prepare
    > requiere que todos los parámetros tengan un tipo establecido de forma explícita."
    >
    > Esto es lo que he hecho pero no se si está bien:
    >
    > Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String,
    >                     type As DbType, value As Object) As DbParameter
    >

    Tienes que asignarle el DbType pasado a la función a la propiedad DbType del objeto DbParameter creado en la función CreateParameterConTipo:

        Public Shared Function CreateParameterConTipo(cmd As DbCommand, name As String,
                        type As DbType, value As Object) As DbParameter
    
           If (cmd Is Nothing) Then
               Throw New ArgumentException("El valor del comando no es válido.")
           End If
    
           Dim param As DbParameter = cmd.CreateParameter()
           param.ParameterName = name
           param.Value = value
    
           ' Le asignamos el tipo de dato al parámetro
           param.DbType = type
    
           Return param
    
        End Function
    

    Y como comentas que el tipo de dato es Double, llamarías a la función de la siguiente manera:

        'Especificamos la consulta SQL de selección
        cmd.Parameters.Add(CreateParameterConTipo(cmd, "@divisor", DbType.Double, VarGlobal.ValorDivisor))

    Prueba de nuevo, pero no sé yo en estos momentos si te va a funcionar por el tipo de consulta SQL de selección con el que deseas configurar la propiedades InsertCommand, UpdateCommand y DeleteCommand de un adaptador de datos.

    Fíjate que estás seleccionando un campo calculado en la consulta SQL de selección:

       cmd.CommandText = "SELECT ..., (ValorContable / @divisor) as ValorContable, ...

    Y la verdad es que no sé si el objeto DbCommandBuilder va a ser capaz de construir las consultas de inserción, actualización y eliminación que necesita ejecutar el método Update del adaptador de datos.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta gemma_campillo jueves, 2 de junio de 2016 7:58
    jueves, 2 de junio de 2016 7:08
    Moderador
  • Hola maestro:

    Pues como siempre si, eso era lo que no sabía hacer.

    Muchas gracias como siempre, querido amigo.

    Un fuerte abrazo.

    Gemma

    jueves, 2 de junio de 2016 8:00
  • Hola Enrique:

    El objeto DbCommandBuilder ha sido capaz de construir correctamente las consultas.

    Un abrazo.

    Gemma

    jueves, 2 de junio de 2016 8:25
  • "gemma_campillo" escribió:

    > El objeto DbCommandBuilder ha sido capaz de construir correctamente las consultas.

    ¡Entonces se ha portado como un "hombretón"! ;-)

    Pensaba que el problema venía por el campo calculado que aparece en la consulta SQL de selección, pero por el resultado satisfactorio que has obtenido, parece ser que basta con asignarle explícitamente el tipo de dato al parámetro en cuestión.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    • Marcado como respuesta gemma_campillo jueves, 2 de junio de 2016 10:54
    jueves, 2 de junio de 2016 8:46
    Moderador
  • Hola maestro:

    <Pensaba que el problema venía por el campo calculado que aparece en la consulta SQL de selección, pero por el resultado satisfactorio que has obtenido, parece ser que basta con asignarle explícitamente el tipo de dato al parámetro en cuestión.>

    Pues no, no funciona, no da ningún error, pero al final no lo graba. Llevabas tu razón en que al CommandBuilder no le gustan los parámetros. En el caso nuestro, pasa de ello, actualiza la grilla pero vuelve a poner los resultados anteriores ya que no lo graba en la base de datos. Le quito el parámetro @divisor y funciona de maravilla, estoy mirando alguna otra forma de hacerlo más rudimentaria.

    Un abrazo querido Enrique.

    Gemma

    jueves, 2 de junio de 2016 10:54