Type conversion error when saving to database

Asked

Viewed 430 times

1

My project has a form frmAdicionarProduto 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 can be integer or decimal number I have no problems.

Example 1: 0,99 = error
Example 2: 1,57 = success

Getting value from profit

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 the data in 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();
    }
}

By clicking the button to add the data, you are returning me the following error:

System.Data.Sqlclient.Sqlexception: 'Error converting varchar data type into Numeric.'

OBS: I left some comments in the codes to facilitate understanding.

1 answer

3


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

Thus:

//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();
    }
}

I put in the Github for future reference.

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

And look about SQL Injection.

So there are some errors in the code:

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

Luckily it went wrong in a situation. You can’t trust what works, you have to be right.

This works, but it’s right?:

Fiat 147 todo bagaçado andando pelas ruas

  • I have to put if in all conversions where you posted the comment //tem que fazer o mesmo do acima,?

  • Yes, you should check if the conversion went well, if it did not go on.

  • I’m almost giving up kkkkkk After all the mistakes set by you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.