ERRO DE CONVERSÃO DE VARCHAR PARA NUMERIC

SANROMAN 10/04/2014 21:17:31
#437176
Olá amigos

Por favor me ajudem a resolver esse erro; O código é o seguinte:

Private Sub geraSaldo()

Dim con As New SqlConnection(strCmd)

con.open()

Try

For Each ListView As ListViewItem In listHistoricoVendas.Items

If (ListView.Checked) Then

Dim valorPago As String = Decimal.Parse(txtValorPago.Text, nfi)
Dim valorSaldo As Decimal = Decimal.Parse(ListView.SubItems(7).Text, nfi)
Dim valorNovoSaldo As Decimal

valorNovoSaldo = valorSaldo - valorPago

ListView.SubItems(7).Text = valorNovoSaldo.ToString([Ô]N[Ô], nfi)

Dim strsql As String = [Ô][Ô]
Dim codVenda As Integer = ListView.Text
Dim strReceber As String = [Ô]SELECT id_FinalizaVenda FROM TB_FinalizaVenda WHERE id_FinalizaVenda =[Ô] & codVenda

cmd = New SqlCommand(strReceber, con)
strReceber = CInt(cmd.ExecuteScalar())
strsql = [Ô]UPDATE TB_FinalizaVenda SET ValorSaldo = [ô][Ô] & valorNovoSaldo & [Ô][ô] WHERE id_FinalizaVenda =[Ô] & codVenda
cmd = New SqlCommand(strsql, con)
cmd.ExecuteNonQuery()

End If

Next

Catch ex As Exception
MsgBox(ex.Message)
End Try

End Sub

Se trabalho com valores do tipo R$ 3,00 faz o update, agora se trabalho com valores do tipo R$ 3,20, ou seja com casas decimais da o seguinte erro:

Erro de conversão de varchar para numeric

O que pode estar acontecendo?
FILMAN 10/04/2014 22:56:14
#437181
Onde acontece o erro?

Mas repare nessas duas linhas

Dim valorPago As [txt-color=#e80000]String[/txt-color] = Decimal.Parse(txtValorPago.Text, nfi)
Dim valorSaldo As [txt-color=#0000f0]Decimal[/txt-color] = Decimal.Parse(ListView.SubItems(7).Text, nfi)
SANROMAN 11/04/2014 12:42:50
#437199
Olá FILMAN

Mudei as linhas para decimal e continua dando o erro. ficou assim:

Dim valorPago As Decimal = Decimal.Parse(txtValorPago.Text, nfi)
Dim valorSaldo As Decimal = Decimal.Parse(ListView.SubItems(7).Text, nfi)

O erro acontece quando executa a linha:

cmd.ExecuteNonQuery()

O valor e mostrado certo no list como mostra a figura abaixo. No momento de executar o update é que acontece o erro.

KERPLUNK 11/04/2014 13:25:48
#437200
Resposta escolhida
1 - O que você quer fazer se resolve com uma única query, não precisa duas
2 - Use parametrização nos seus comandos que esses problemas desaparecem, junto com outros que você ainda nem sabe que tem, como SQL Injection
SANROMAN 11/04/2014 13:44:32
#437203
Olá Kerplunk

Muito obrigado pelo toque. O código ficou assim e funcionou perfeitamente.

Private Sub GeraSaldo()

sqlCon.Open()

Try

For Each ListView As ListViewItem In listHistoricoVendas.Items

If (ListView.Checked) Then

Dim codVenda As Integer = ListView.Text
Dim valorPago As Decimal = Decimal.Parse(txtValorPago.Text, nfi)
Dim valorSaldo As Decimal = Decimal.Parse(ListView.SubItems(7).Text, nfi)
Dim valorNovoSaldo As Decimal

valorNovoSaldo = valorSaldo - valorPago

ListView.SubItems(7).Text = valorNovoSaldo.ToString([Ô]N[Ô], nfi)

With sqlCmd
.CommandType = CommandType.Text
.CommandText = [Ô][Ô]
.CommandText = [Ô]UPDATE TB_FinalizaVenda SET ValorSaldo = @ValorSaldo WHERE id_FinalizaVenda = [Ô] & codVenda

.Connection = sqlCon

.Parameters.Add(New SqlParameter([Ô]@ValorSaldo[Ô], SqlDbType.Decimal)).Value = ListView.SubItems(7).Text

End With
End If
Next

sqlCmd.ExecuteNonQuery()

Catch ex As Exception
MsgBox(ex.Message)
Finally
sqlCmd.Parameters.Clear()
sqlCon.Close()
End Try

End Sub

Irei usar parâmetros em todo o projeto.

Gostaria de agradecer ao FILMAN, que sempre se mostrou disposto a ajudar.


Até a próxima.
OCELOT 11/04/2014 14:51:51
#437204
O problema é que você está concatenando valores na SQL, e quando o valor tem casas decimais ele é automaticamente convertido para string na hora que é concatenado e nessa conversão o separador decimal usado é o padrão do sistema operacional, no caso é usado a vírgula.

Só que o problema é que na SQL não se pode usar vírgula como separador decimal, nela deve sempre ser usado o ponto como separador decimal pois a vírgula é usada como delimitador de expressões.

Suas alternativas são usar parâmetros em vez de concatenar strings na SQL, que é a melhor opção, ou trocar a virgula por ponto na hora de montar a SQL

O caminho fácil seria trocar na parte que monta a sua SQL em que está assim

& valorNovoSaldo &

por

& valorNovoSaldo.ToString().Replace([Ô],[Ô], [Ô].[Ô]) &

Mas o melhor mesmo é você estudar sobre o uso de parâmetros, eles resolvem muitos problemas que se pode ter com SQL
Tópico encerrado , respostas não são mais permitidas