Type conversion error when saving to database

0

My project has a frmAdicionarProduto form to add products to the database containing TextBox and ComboBox :

txtProduto  
txtQuantidade  
cmbTipo  
txtValorFornecedor  
txtValorFinal  
txtLucro  

I'm having trouble saving values below 1 integer.

I have problems only with numbers below 1, above 1 it may be integer or decimal that I have no problems.

Example 1: 0.99 = Error Example 2: 1.57 = Success

Getting profit value

private void txtValorFinal_TextChanged(object sender, EventArgs e)
{
    double lucro; // Criação da variável que ira comportar o valor do lucro
    lucro = Convert.ToDouble(txtValorFinal.Text) - Convert.ToDouble(txtValorFornecedor.Text); // Cálculo do lucro e comportando o valor na variável lucro
    txtLucro.Text = lucro.ToString("0.00"); // Populando o TextBox txtLucro com o valor da variável lucro
}

Adding data to the database

string strConn = "Data Source=DESKTOP-AJLR3DB\SQLEXPRESS;Initial Catalog=DBGestor;Integrated Security=True";
Ado insert = new Ado(strConn);
insert.InsertProduto(txtNomeProduto.Text,
    Convert.ToInt32(txtQuantidade.Text),
    cmbTipo.Text,
    Convert.ToDouble(txtValorFornecedor.Text),
    Convert.ToDouble(txtValorFinal.Text),
    Convert.ToDouble(txtLucro.Text));
MessageBox.Show("Produto cadastrado com sucesso!", "Sucesso!", MessageBoxButtons.OK);
this.Close();
this.Dispose();

Ado.cs

string ConectionString;

public void InsertProduto(string nomeProduto, int quantidade, string tipo, double valorFornecedor, double valorFinal, double lucro)
{
    SqlConnection conn = new SqlConnection(ConectionString);
    string cmdString = "INSERT INTO produtos VALUES ('" + nomeProduto.ToString() +
        "', '" + quantidade +
        "', '" + tipo.ToString() +
        "', '" + valorFornecedor +
        "', '" + valorFinal +
        "', '" + lucro + "')";

    try
    {
        conn.Open();
        SqlCommand cmd = new SqlCommand(cmdString, conn);
        cmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        throw ex; // Essa linha é setada com o erro descrito no fim da pergunta
    }
    finally
    {
        conn.Close();
        conn.Dispose();
    }
}

When I click on the button to add the data, I am returning the following error:

  

System.Data.SqlClient.SqlException: 'Error converting varchar data type to numeric.'

OBS: I left some comments in the codes to make it easier to understand.

    
asked by anonymous 25.04.2018 / 01:20

1 answer

2

The right way to convert is like this:

private void txtValorFinal_TextChanged(object sender, EventArgs e) {
    if (decimal.TryParse(txtValorFinal.Text, out var valorFinal) && decimal.TryParse(txtValorFornecedor.Text, out var valorFornecedor)) {
        txtLucro.Text = (valorFinal - valorFornecedor).ToString("0.00");
    } else {
        //tratar o erro aqui
    }
}

//essa classe Ado parece desnecessária ou mal formulada
var insert = new Ado("Data Source=DESKTOP-AJLR3DB\SQLEXPRESS;Initial Catalog=DBGestor;Integrated Security=True");
insert.InsertProduto(txtNomeProduto.Text,
    //tem que fazer o mesmo do acima,
    cmbTipo.Text,
    //tem que fazer o mesmo do acima,
    //tem que fazer o mesmo do acima,
    //tem que fazer o mesmo do acima);
MessageBox.Show("Produto cadastrado com sucesso!", "Sucesso!", MessageBoxButtons.OK);
    //e se der erro?
this.Close(); //duvido que isto está correto aqui
this.Dispose(); //quase certo que não deveria estar aqui

So:

//o mais certo é receber um objeto com estas propriedades e não esse monte de parâmetro
public void InsertProduto(string nomeProduto, int quantidade, string tipo, decimal valorFornecedor, decimal valorFinal, decimal lucro) {
    using (var conn = new SqlConnection(ConectionString)) {
        conn.Open();
        //não sei o nome das colunas no banco de dados chuetei o que deveria ser
        var cmString = "INSERT INTO produtos (Nome, Quantidade, Tipo, ValorFornecedor, ValorFinal, Lucro) VALUES (@Nome, @Quantidade, @Tipo, @ValorFornecedor, @ValorFinal, @Lucro";
        var cmd = new SqlCommand(cmdString, conn);
        cmd.Parameters.AddWithValue("@Nome", nomeProduto);
        cmd.Parameters.AddWithValue("@Quantidade", quantidade);
        cmd.Parameters.AddWithValue("@Tipo", tipo);
        cmd.Parameters.AddWithValue("@ValorFornecedor", valorFornecedor);
        cmd.Parameters.AddWithValue("@ValorFinal", valorFinal);
        cmd.Parameters.AddWithValue("@Lucro", lucro);
        cmd.ExecuteNonQuery();
    }
}

See What is the correct way to use float, double, and decimal types? .

And look for SQL Injection.

Then there are some errors in the code:

  • You are converting in a way that generates error, you have to check if it worked.
  • You are using binary floating point for monetary value, it must be decimal.
  • You are treating exception, and in a very wrong way (it will only have 3 errors in the exception) when the correct one is to use using .
  • You are allowing SQL Injection when you should parameterize query .
  • You are abusing parameters when you should use an object
  • You have something in the wrong place.
  • Probably the Lucro field should not exist in the database because it is duplicate information, but it depends on the context to be sure.

Luckily, it made a mistake in a situation. You can not trust what works, you have to be right.

This works:

    
25.04.2018 / 01:40