ERRO EM UPDATE SQL SERVER

SANROMAN 24/07/2024 16:49:47
#503447
Boa tarde, amigos,

O código a seguir atualiza uma tabela sqlserver:

Private Sub atualizaVendaDelivery()

Using con As SqlConnection = conectarSqlServer()

con.Open()

Try
Using strCom As SqlCommand = New SqlCommand("UPDATE TB_VendaDelivery SET CodProduto = @CodProduto, Produto = @Produto, PrecoUnitario = @PrecoUnitario, Qtde= @Qtde, TotalVenda = @TotalVenda, " &
"NumCaixa = @NumCaixa, NumPedido = @NumPedido, Duracao = @Duracao, DataHoraInicio = @DataHoraInicio, CodCliente = @CodCliente, NomeCliente = @NomeCliente, " &
"NumTel = @NumTel, StatusPedido = @StatusPedido, TotalDesconto = @TotalDesconto, TotalTaxa = @TotalTaxa, TotalFinal = @TotalFinal, EmEspera = @EmEspera, " &
"EmPreparo = @EmPreparo, Entregar = @Entregar, EmTransito = @EmTransito, Entregue = @Entregue, Pago = @Pago, Endereco = @Endereco, NumEnd = @NumEnd, " &
"Bairro = @Bairro, Cidade = @Cidade, Estado = @Estado, MeioPgto = @MeioPgto, Referencia = @Referencia, TotalPago = @TotalPago, TotalTroco = @TotalTroco, " &
"Cep = @Cep, CpfCnpj = @CpfCnpj, TipoEntrega = @TipoEntrega, TipoTransporte = @TipoTransporte, Obs = @Obs, FormaPgto = @FormaPgto " &
"WHERE NumPedido = @numped", con)

strCom.Parameters.AddWithValue("@numped", txtNumPedido.Text)

Dim duracao As TimeSpan = TimeSpan.Parse(lblTempoTotal.Text)
Dim contato As TimeSpan = TimeSpan.Parse(lblEmEspera.Text)
Dim preparo As TimeSpan = TimeSpan.Parse(lblEmPreparo.Text)
Dim entrega As TimeSpan = TimeSpan.Parse(lblARetirar.Text)
Dim transito As TimeSpan = TimeSpan.Parse(lblEmTransito.Text)
Dim entregue As TimeSpan = TimeSpan.Parse(lblTempoTotal.Text)

With strCom
For i As Integer = 0 To listVendaDiretaBalcao.Items.Count - 1
.Parameters.Add(New SqlParameter("@Qtde", SqlDbType.Int)).Value = listVendaDiretaBalcao.Items(i).SubItems(1).Text
.Parameters.Add(New SqlParameter("@CodProduto", SqlDbType.Int)).Value = listVendaDiretaBalcao.Items(i).SubItems(2).Text
.Parameters.Add(New SqlParameter("@Produto", SqlDbType.NVarChar)).Value = listVendaDiretaBalcao.Items(i).SubItems(3).Text
.Parameters.Add(New SqlParameter("@PrecoUnitario", SqlDbType.Decimal)).Value = CDec(listVendaDiretaBalcao.Items(i).SubItems(4).Text)
.Parameters.Add(New SqlParameter("@TotalVenda", SqlDbType.Decimal)).Value = CDec(listVendaDiretaBalcao.Items(i).SubItems(5).Text)
.Parameters.Add(New SqlParameter("@NumCaixa", SqlDbType.NVarChar)).Value = lblNumCX.Text
.Parameters.Add(New SqlParameter("@NumPedido", SqlDbType.Int)).Value = txtNumPedido.Text
.Parameters.Add(New SqlParameter("@DataHoraInicio", SqlDbType.DateTime)).Value = txtDataHoraInicio.Text
.Parameters.Add(New SqlParameter("@Duracao", SqlDbType.Time)).Value = duracao
.Parameters.Add(New SqlParameter("@DataHoraEntrega", SqlDbType.DateTime)).Value = DateTime.Now
.Parameters.Add(New SqlParameter("@CodCliente", SqlDbType.Int)).Value = txtCodCliente.Text
.Parameters.Add(New SqlParameter("@NomeCliente", SqlDbType.NVarChar)).Value = txtNome.Text
.Parameters.Add(New SqlParameter("@NumTel", SqlDbType.NVarChar)).Value = txtTelefone.Text
.Parameters.Add(New SqlParameter("@CpfCnpj", SqlDbType.NVarChar)).Value = txtCPF.Text
.Parameters.Add(New SqlParameter("@Pago", SqlDbType.NVarChar)).Value = txtPago.Text
.Parameters.Add(New SqlParameter("@Obs", SqlDbType.NVarChar)).Value = txtObs.Text

If rdbEmEspera.Checked = True Then
.Parameters.Add(New SqlParameter("@StatusPedido", SqlDbType.NVarChar)).Value = rdbEmEspera.Text
ElseIf rdbEmPreparo.Checked = True Then
.Parameters.Add(New SqlParameter("@StatusPedido", SqlDbType.NVarChar)).Value = rdbEmPreparo.Text
ElseIf rdbARetirar.Checked = True Then
.Parameters.Add(New SqlParameter("@StatusPedido", SqlDbType.NVarChar)).Value = rdbARetirar.Text
ElseIf rdbEmTransito.Checked = True Then
.Parameters.Add(New SqlParameter("@StatusPedido", SqlDbType.NVarChar)).Value = rdbEmTransito.Text
ElseIf rdbEntregue.Checked = True Then
.Parameters.Add(New SqlParameter("@StatusPedido", SqlDbType.NVarChar)).Value = rdbEntregue.Text
End If

.Parameters.Add(New SqlParameter("@TotalDesconto", SqlDbType.Decimal)).Value = CDec(txtDescontoPercentual.Text)
.Parameters.Add(New SqlParameter("@TotalTaxa", SqlDbType.Decimal)).Value = CDec(txtValorEntrega.Text)
.Parameters.Add(New SqlParameter("@TotalFinal", SqlDbType.Decimal)).Value = CDec(txtTotalPagarVenda.Text)
.Parameters.Add(New SqlParameter("@TotalPago", SqlDbType.Decimal)).Value = CDec(txtValorPagoVenda.Text)
.Parameters.Add(New SqlParameter("@TotalTroco", SqlDbType.Decimal)).Value = CDec(txtValorTrocoVenda.Text)
.Parameters.Add(New SqlParameter("@EmEspera", SqlDbType.Time)).Value = contato
.Parameters.Add(New SqlParameter("@EmPreparo", SqlDbType.Time)).Value = preparo
.Parameters.Add(New SqlParameter("@Entregar", SqlDbType.Time)).Value = entrega
.Parameters.Add(New SqlParameter("@EmTransito", SqlDbType.Time)).Value = transito
.Parameters.Add(New SqlParameter("@Entregue", SqlDbType.Time)).Value = entregue
.Parameters.Add(New SqlParameter("@Endereco", SqlDbType.NVarChar)).Value = txtEndereco.Text
.Parameters.Add(New SqlParameter("@NumEnd", SqlDbType.NVarChar)).Value = txtNumEnd.Text
.Parameters.Add(New SqlParameter("@Bairro", SqlDbType.NVarChar)).Value = txtBairro.Text
.Parameters.Add(New SqlParameter("@Cidade", SqlDbType.NVarChar)).Value = txtCidade.Text
.Parameters.Add(New SqlParameter("@Estado", SqlDbType.NVarChar)).Value = txtEstado.Text
.Parameters.Add(New SqlParameter("@Referencia", SqlDbType.NVarChar)).Value = txtReferencia.Text
.Parameters.Add(New SqlParameter("@Cep", SqlDbType.NVarChar)).Value = txtCep.Text
.Parameters.Add(New SqlParameter("@TipoEntrega", SqlDbType.NVarChar)).Value = cbTipoEntrega.Text
.Parameters.Add(New SqlParameter("@TipoTransporte", SqlDbType.NVarChar)).Value = cbTipoTranspsorte.Text
.Parameters.Add(New SqlParameter("@FormaPgto", SqlDbType.NVarChar)).Value = cbFormaPagamentoVenda.Text
.Parameters.Add(New SqlParameter("@MeioPgto", SqlDbType.NVarChar)).Value = cbMeioPgtoVenda.Text

strCom.ExecuteNonQuery()
strCom.Parameters.Clear()
Next

End With
End Using

Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Using

End Sub


Se possuo apenas um produto para atualizar funciona. Se tenho dois ou mais produtos para atualizar aparece o seguinte erro:

"É necessário declarar a variável escalar '@numped'"

Já tentei resolver, mas não consegui. Se alguém puder me ajudar desde já agradeço
KERPLUNK 25/07/2024 12:23:34
#503450
Acho que é porque você já está referenciando esse campo na query, no caso o campo "NumPedido". Experimente tirar ele do update e deixar só na cláusula de "where". Se você está usando ele como cláusula where, significa que ele não vai mudar mesmo.
NILSONTRES 25/07/2024 12:34:22
#503451
Citação:

strCom.Parameters.AddWithValue("@numped", txtNumPedido.Text)


Esse parâmetro não teria que entrar dentro do For ?
SANROMAN 25/07/2024 13:23:04
#503453
Bom dia, NILSONTRES e KERPLUNK,

Já tentei das duas formas:
Tirando NumPedido da consulta dá o mesmo erro: "É necessário declarar a variável escalar '@numped'"
Colocando o parâmetro no laço for não dá o erro, mas copia a última linha para todos os produtos envolvidos.
Será, que não preciso fazer uma consulta aos dados e depois relacioná-la ao UPDATE.

Tenham um ótimo dia
DAMASCENO.CESAR 14/08/2024 13:23:11
#503491
Não sei se entendi direito, mas...
Você está fazendo Update no mesmo número do pedido, esse não é alterado, então seu FOR faz todas as alterações e só permanece a última feita nesse número de pedido. Se você tem um ID para cada registro na tabela, use ele para fazer o UPDATE, agora se você está acrescentando itens no pedido, e o número do pedido continua o mesmo, o correto é um INSERT.
Se o número do pedido se repete na tabela, é necessário o UPDATE pelo ID, ou qual seja seu índice primário.
KERPLUNK 15/08/2024 13:00:28
#503492
Outra coisa que reparei agora:
Tem um bloco condicional ali(um If). Ele se baseia em checkboxes. Se mais de uma checkbox estiver checada, ele vai adicionar parâmetro duplicado.

Além disso, como já comentado, a atribuição do "numped" deveria estar no bloco for e você deveria adicionar também a condicional de código de produto no WHERE, assim, não vai duplicar a mesma coisa pra todos os produtos do pedido.
LEONARDOVF 16/08/2024 14:35:29
#503493
Alterado em 16/08/2024 14:36:29
seu código que criar o parâmetro @numped está fora do for, então

  

strCom.Parameters.AddWithValue("@numped", txtNumPedido.Text)

Dim duracao As TimeSpan = TimeSpan.Parse(lblTempoTotal.Text)
Dim contato As TimeSpan = TimeSpan.Parse(lblEmEspera.Text)
Dim preparo As TimeSpan = TimeSpan.Parse(lblEmPreparo.Text)
Dim entrega As TimeSpan = TimeSpan.Parse(lblARetirar.Text)
Dim transito As TimeSpan = TimeSpan.Parse(lblEmTransito.Text)
Dim entregue As TimeSpan = TimeSpan.Parse(lblTempoTotal.Text)

With strCom
For i As Integer = 0 To listVendaDiretaBalcao.Items.Count - 1


depois de executado, vc limpa todos todos os parâmetros, dai não tem mais o parâmetro @numped.


  
strCom.ExecuteNonQuery()
strCom.Parameters.Clear()
Next
KERPLUNK 16/08/2024 17:22:26
#503494
Pois é, está aí mais uma coisa que usando OOP, facilitaria uma barbaridade.
Ao invés de basear-se num grid, você tem uma lista de objetos. O grid, liga direto com essa lista e atualiza valores na lista. Ao gravar, simplesmente se grava a lista.
Muito menos código, muito menos complicação e muito mais organizado.
Faça seu login para responder