none
Actualizar imagen de SQL desde Vb.net

    Pregunta

  • Hola tengo una consulta que me esta rompiendo la cabeza y no se como solucionarlo, tengo esta fuente:

    Private Sub btn_Guardar_Click_1(sender As Object, e As EventArgs) Handles btn_Guardar.Click
            Try
                If validar() = True Then
                    MsgBox("Algunos campos obligatorios están vacíos.", vbExclamation)
                    txt_RazonSocial.Focus()
                Else
                    If (cn.State = ConnectionState.Open) Then
                        cn.Close()
                    End If
                    cliente.correo = txt_correo_cli.Text
                    cliente.direccion = txt_dir_cli.Text
                    cliente.fecharegistro = dtp_fec_reg_cli.Value.ToString
                    cliente.iddistrito = CInt(cbo_id_dist.SelectedValue)
                    cliente.idtipocliente = CInt(cbo_id_tip_cli.SelectedValue)
                    cliente.razonsocial = txt_RazonSocial.Text
                    cliente.ruccliente = txt_ruc_cli.Text
                    cliente.telefono = txt_telef_cli.Text
                    cliente.web = txt_web_cli.Text

                    Dim arrFilename() As String = Split(Text, "\")
                    Array.Reverse(arrFilename)
                    Dim ms As New MemoryStream
                    picAvatar.Image.Save(ms, picAvatar.Image.RawFormat)
                    Dim arrImage() As Byte = ms.GetBuffer

                    clienteDAO.agregar(cliente, arrImage)
                End If
            Catch ex As Exception
                MsgBox("Error" & ex.ToString)
            End Try
            txt_RazonSocial.Focus()
            dgv_Clientes.DataSource = clienteDAO.ConsultaClientes()
            Limpiar()
        End Sub

    Todo esto me permite almacenar la informacion con imagenes en una BD de SQl Server, hasta ahi todo correcto no tengo problema alguno, el siguiente codigo es en el boton editar:

    Private Sub btn_Editar_Click(sender As Object, e As EventArgs) Handles btn_Editar.Click
            Try
                Quest = MsgBox("Quiere modificar el registro?", vbYesNo + vbQuestion, "Consulta")
                If Quest = vbYes Then
                    clienteDAO.ActualizarCampos(txt_IdCliente.Text, txt_RazonSocial.Text, txt_ruc_cli.Text, txt_dir_cli.Text, cbo_id_tip_cli.SelectedValue, cbo_id_dist.SelectedValue, txt_telef_cli.Text, txt_correo_cli.Text, txt_web_cli.Text)

                    MsgBox("Registro actualizado correctamente", vbInformation, "Resultado")

                ElseIf Quest = vbNo Then
                    'nada
                End If
                dgv_Clientes.DataSource = clienteDAO.ConsultaClientes()
            Catch ex As SqlException
                MsgBox("ERROR EN SQL: " & ex.ToString)
            Catch evb As Exception
                MsgBox("ERROR: " & evb.ToString)
            End Try
        End Sub

    Este codigo me permite editar casi todas las columnas de la tabla menos 1, si esa, el de la imagen, la pregunta es, Donde debo insertar el comando adicional para que me pertmita editar y/o reemplazar o actualizar la imagen para cambiarla por otra. espero pueda esta comunidad ayudarme como siempre lo viene haciendo, muchas gracias.


    Juan Fernando

    jueves, 6 de octubre de 2016 4:56

Respuestas

  • Hola JuanfernandoDj,

    [-] ... El detalle es que al darle modificar actualiza toooodos los registros al mismo dato

    Lo que pasa es que nunca asignas un Where en tu consulta, por lo que actualiza todos los campos. Tienes que actualizar los valores según el Id del cliente :

    Al final de tu consulta quedaría :

    ....id_tip_cli = @id_tip_cli, Fotografia = @Fotografia Where id_cli = @id"

    Y cuando envíes el valor :

    da.Parameters.Add("@id", SqlDbType.Int)
    ....
    da.Parameters("@id").Value = El_id_del_cliente

    Así cuando actualices el registro, solo modificará los campos de ese cliente.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta Juan_fernando domingo, 9 de octubre de 2016 2:30
    domingo, 9 de octubre de 2016 1:03
  • Hola JuanfernandoDj,

    No, puedes obtenerlo de la grilla directamente :

     da.Parameters("@id").Value = Convert.ToInt32(DataGridView1.CurrentRow.Cells(0).Value.ToString)

    O usando :

    ...Value = CInt(DataGridView1.CurrentRow.Cells("id_cli").Value.ToString())

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta Juan_fernando domingo, 9 de octubre de 2016 2:31
    domingo, 9 de octubre de 2016 1:35
  • Fíjate que cuando grabas el registro, lo haces a través de una capa de datos en la que tienes clienteDAO.agregar(cliente, imagen). Y cuando quieres modificarlo, llamas a clienteDAO.ActualizarCampos(...datos...).

    Pues bien, lo razonable sería que ya que estás usando una capa de acceso a datos (clienteDAO), que sea esa capa la que contenga el método para actualizar la imagen. Por simetría con la grabación inicial ("agregar"), lo lógico sería modificar el método ActualizarCampos para que también reciba al final un parámetro más con el array de bytes de la imagen (el cual construirías antes de pasárselo en la misma manera que lo haces durante la inserción inicial).

    Eso requerirá modificar el clienteDAO para que grabe la imagen. Probablemente ya tienes el código necesario puesto que lo usas dentro de agregar; no hay más que reproducir un mecanismo similar al que ya tengas ahí dentro pero metiéndolo en el Update en lugar del Insert. Si tuvieras dudas con esto, muéstranos cómo es el clienteDAO y veremos cómo se puede modificar.

    jueves, 6 de octubre de 2016 7:03

Todas las respuestas

  • Fíjate que cuando grabas el registro, lo haces a través de una capa de datos en la que tienes clienteDAO.agregar(cliente, imagen). Y cuando quieres modificarlo, llamas a clienteDAO.ActualizarCampos(...datos...).

    Pues bien, lo razonable sería que ya que estás usando una capa de acceso a datos (clienteDAO), que sea esa capa la que contenga el método para actualizar la imagen. Por simetría con la grabación inicial ("agregar"), lo lógico sería modificar el método ActualizarCampos para que también reciba al final un parámetro más con el array de bytes de la imagen (el cual construirías antes de pasárselo en la misma manera que lo haces durante la inserción inicial).

    Eso requerirá modificar el clienteDAO para que grabe la imagen. Probablemente ya tienes el código necesario puesto que lo usas dentro de agregar; no hay más que reproducir un mecanismo similar al que ya tengas ahí dentro pero metiéndolo en el Update en lugar del Insert. Si tuvieras dudas con esto, muéstranos cómo es el clienteDAO y veremos cómo se puede modificar.

    jueves, 6 de octubre de 2016 7:03
  • Hola Alberto, ya hice el cambio de la sentencia UPDATE, queda asi:

    En la clase DAO:

     Public Sub Modificar(clientes As Clientes, image() As Byte)
            Try
                Dim da As New SqlCommand
                da.Connection = cn
                da.CommandText = "Update Cliente set RazonSocial = @RazonSocial, ruc_cli = @ruc_cli, dir_cli = @dir_cli,id_dist = @id_dist ,telef_cli = @telef_cli, correo_cli = @correo_cli, web_cli = @web_cli, fec_reg_cli = @fec_reg_cli, id_tip_cli = @id_tip_cli, Fotografia = @Fotografia"

                da.Parameters.Add("@RazonSocial", SqlDbType.VarChar, 50)
                da.Parameters.Add("@ruc_cli", SqlDbType.Char, 11)
                da.Parameters.Add("@dir_cli", SqlDbType.VarChar, 47)
                da.Parameters.Add("@id_dist", SqlDbType.Int)
                da.Parameters.Add("@telef_cli", SqlDbType.VarChar, 17)
                da.Parameters.Add("@correo_cli", SqlDbType.VarChar, 40)
                da.Parameters.Add("@web_cli", SqlDbType.VarChar, 50)
                da.Parameters.Add("@fec_reg_cli", SqlDbType.DateTime)
                da.Parameters.Add("@id_tip_cli", SqlDbType.Int)
                da.Parameters.Add("@Fotografia", SqlDbType.Image)

                da.Parameters("@RazonSocial").Value = clientes.razonsocial
                da.Parameters("@ruc_cli").Value = clientes.ruccliente
                da.Parameters("@dir_cli").Value = clientes.direccion
                da.Parameters("@id_dist").Value = clientes.iddistrito
                da.Parameters("@telef_cli").Value = clientes.telefono
                da.Parameters("@correo_cli").Value = clientes.correo
                da.Parameters("@web_cli").Value = clientes.web
                da.Parameters("@fec_reg_cli").Value = clientes.fecharegistro
                da.Parameters("@id_tip_cli").Value = clientes.idtipocliente
                da.Parameters("@Fotografia").Value = image

                cn.Open()
                da.ExecuteNonQuery()
                cn.Close()

                MsgBox("Se actualizó el registro", vbInformation)

            Catch ex As SqlException
                MsgBox("ERROR EN SQL: " & ex.ToString)
            Catch e As Exception
                MsgBox("ERROR: " & e.ToString)
            End Try
        End Sub

    En el FORM:

     Private Sub btn_Editar_Click(sender As Object, e As EventArgs) Handles btn_Editar.Click
            Try
                Dim id_cli As String = dgv_Clientes.Item(0, dgv_Clientes.CurrentRow.Index).Value
                cliente.razonsocial = txt_RazonSocial.Text
                cliente.ruccliente = txt_ruc_cli.Text
                cliente.direccion = txt_dir_cli.Text
                cliente.idtipocliente = cbo_id_tip_cli.SelectedValue
                cliente.iddistrito = cbo_id_dist.SelectedValue
                cliente.telefono = txt_telef_cli.Text
                cliente.correo = txt_correo_cli.Text
                cliente.web = txt_web_cli.Text

                Dim arrFilename() As String = Split(Text, "\")
                Array.Reverse(arrFilename)
                Dim ms As New MemoryStream
                picAvatar.Image.Save(ms, picAvatar.Image.RawFormat)
                Dim arrImage() As Byte = ms.GetBuffer

                clienteDAO.Modificar(cliente, arrImage)

                dgv_Clientes.DataSource = clienteDAO.ConsultaClientes()


            Catch ex As Exception

            End Try

    End Sub

    El detalle es que al darle modificar actualiza toooodos los registros al mismo dato XDXDXD, gracias. 


    Juan Fernando

    domingo, 9 de octubre de 2016 0:50
  • Hola JuanfernandoDj,

    [-] ... El detalle es que al darle modificar actualiza toooodos los registros al mismo dato

    Lo que pasa es que nunca asignas un Where en tu consulta, por lo que actualiza todos los campos. Tienes que actualizar los valores según el Id del cliente :

    Al final de tu consulta quedaría :

    ....id_tip_cli = @id_tip_cli, Fotografia = @Fotografia Where id_cli = @id"

    Y cuando envíes el valor :

    da.Parameters.Add("@id", SqlDbType.Int)
    ....
    da.Parameters("@id").Value = El_id_del_cliente

    Así cuando actualices el registro, solo modificará los campos de ese cliente.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta Juan_fernando domingo, 9 de octubre de 2016 2:30
    domingo, 9 de octubre de 2016 1:03
  • Ah ok, pero en donde dice:

    da.Parameters("@id").Value = El_id_del_cliente

     debería especificar un Id preterteminado y lo que quiero es que sea cualquiera que yo elija en la grilla.


    Juan Fernando

    domingo, 9 de octubre de 2016 1:31
  • Hola JuanfernandoDj,

    No, puedes obtenerlo de la grilla directamente :

     da.Parameters("@id").Value = Convert.ToInt32(DataGridView1.CurrentRow.Cells(0).Value.ToString)

    O usando :

    ...Value = CInt(DataGridView1.CurrentRow.Cells("id_cli").Value.ToString())

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta Juan_fernando domingo, 9 de octubre de 2016 2:31
    domingo, 9 de octubre de 2016 1:35
  • Muchas gracias por ayuda, tema solucionado.


    Juan Fernando

    domingo, 9 de octubre de 2016 2:32