none
error al convertir un valor nvarchar a numeric c# asp.net RRS feed

  • Pregunta

  • Saludos amigos

    Tengo un problema al intentar insertar un valor valor en la base de datos me dice el siguiente error "Error al convertir el tipo de datos de varchar a numeric"

    Estoy usando SQL Server 2016 y visual studio 2017 web c#.

    en la base de datos el campo que me esta dando problema es el que dice Cua_DiferenciaDolarC esta declarado como decimal (18,2)

    el textbox que manda a almacenar se llama TxtDiferenciaMonedaDC.

    se que mi problema es que esta mandando los datos crudamente con punto y coma a la base de datos y el datos lo manda de la siguiente manera: -1,200.20, es numérico total y cuando intento insertarlo me arroja el error.

    porque mandar los datos en negativo, porque es el resultado de una operación aritmética, el dato puede cambiar a negativo, positivo o cero dependiendo del resultado que arroje la operación.

    realmente muchachos no se que hacer ayúdenme por favor, díganme que hacer o si pueden ayudarme con el código solo el campo que es decimal.

    dejo el código:

    con2.Close();
                            con2.Open();
                            SqlCommand cmd = new SqlCommand("INSERT INTO Cuadre (Cua_Fecha, Cua_Hora, Cua_Usuario, Cua_Caja, Cua_DolarC, Cua_Franco, Cua_Euro, Cua_Libra, Cua_Yen, Cua_DolarE, Cua_Peso, Cua_DiferenciaDolarC)values(('" + this.TxtFecha.Text + "'), CAST(GETDATE() AS TIME), ('" + this.LblUsuario.Text + "'), ('" + this.DdlCaja.Text + "'), ('" + this.TxtNombreDC.Text + "'), ('" + this.TxtNombreFS.Text + "'), ('" + this.TxtNombreEO.Text + "'), ('" + this.TxtNombreLE.Text + "'), ('" + this.TxtNombreYJ.Text + "'), ('" + this.TxtNombreDE.Text + "'), ('" + this.TxtNombrePD.Text + "'), ('" + this.TxtDiferenciaMonedaDC.Text + "'))", con2);
                            cmd.ExecuteNonQuery();

                            ImgBarras.ImageUrl = "~/Imagenes/BarraVerde.png";
                            LblMensajes.Text = "Registro Guardado Exitosamente";

                            DdlCaja.Enabled = false;
                            Calendario.Enabled = false;

                            TxtNombreDC.ReadOnly = true;
                            TxtNombreFS.ReadOnly = true;
                            TxtNombreEO.ReadOnly = true;
                            TxtNombreLE.ReadOnly = true;
                            TxtNombreYJ.ReadOnly = true;
                            TxtNombreDE.ReadOnly = true;
                            TxtNombrePD.ReadOnly = true;

                            ImageButtonCancelar.Enabled = false;
                            ImageButtonCuadre.Enabled = false;
                            ImageButtonAceptar.Enabled = false;
                            ImgeButtonNuevo.Enabled = true;
                            ImageButtonImprimir.Enabled = true;
                        
                            con2.Close();


    martes, 22 de mayo de 2018 11:01

Respuestas

  • En una sentencia SQL, los datos numericos se deben insertar SIN SEPARADOR DE MILES y con punto decimal (no coma). En tu caso concreto el problema esta causado por la coma en "-1,200.20".

    La solucion mas rudimentaria es usar un "Replace" para quitarla:

    ... (" + this.TxtDiferenciaMonedaDC.Text.Replace(",", "") + ") ...

    Ah, y te he quitado en el ejemplo las comillas simples que lo rodean, que no se requieren para datos de tipo numerico.

    Sin embargo, observa que estas haciendo lo que nunca se debe hacer: estas concatenando datos introducidos por el usuario en una sentencia SQL. No te explico nada al respecto porque sobre este tema se han vertido rios de tinta, y hay en los foros miles de mensajes con ejemplos de como se debe parametrizar la sentencia para evitar los riesgos de la concatenacion.

    • Marcado como respuesta agustin173 jueves, 24 de mayo de 2018 10:18
    martes, 22 de mayo de 2018 12:14
  • Saludos

    Intenta parsear primero el numero para asegurarte de que sea un numero.

    Ej:

    Double TxtDiferenciaMonedaDC = Double.Parse(this.TxtDiferenciaMonedaDC.Text);

    Si te arroja error significa que tu configuración regional no es capaz de convertir lo que tienes a numero entonces podrías eliminar los puntos o las comas dependiendo de cual sea tu separador de miles.

    this.TxtDiferenciaMonedaDC.Text.Replace(",", "")

    • Marcado como respuesta agustin173 jueves, 24 de mayo de 2018 10:18
    martes, 22 de mayo de 2018 13:31

Todas las respuestas

  • En una sentencia SQL, los datos numericos se deben insertar SIN SEPARADOR DE MILES y con punto decimal (no coma). En tu caso concreto el problema esta causado por la coma en "-1,200.20".

    La solucion mas rudimentaria es usar un "Replace" para quitarla:

    ... (" + this.TxtDiferenciaMonedaDC.Text.Replace(",", "") + ") ...

    Ah, y te he quitado en el ejemplo las comillas simples que lo rodean, que no se requieren para datos de tipo numerico.

    Sin embargo, observa que estas haciendo lo que nunca se debe hacer: estas concatenando datos introducidos por el usuario en una sentencia SQL. No te explico nada al respecto porque sobre este tema se han vertido rios de tinta, y hay en los foros miles de mensajes con ejemplos de como se debe parametrizar la sentencia para evitar los riesgos de la concatenacion.

    • Marcado como respuesta agustin173 jueves, 24 de mayo de 2018 10:18
    martes, 22 de mayo de 2018 12:14
  • Saludos

    Intenta parsear primero el numero para asegurarte de que sea un numero.

    Ej:

    Double TxtDiferenciaMonedaDC = Double.Parse(this.TxtDiferenciaMonedaDC.Text);

    Si te arroja error significa que tu configuración regional no es capaz de convertir lo que tienes a numero entonces podrías eliminar los puntos o las comas dependiendo de cual sea tu separador de miles.

    this.TxtDiferenciaMonedaDC.Text.Replace(",", "")

    • Marcado como respuesta agustin173 jueves, 24 de mayo de 2018 10:18
    martes, 22 de mayo de 2018 13:31
  • Alberto a tu comentario o me quieres decir, es que debo parametrizar para insetar los datos a la base de datos.

    es la forma correcta o no.

    martes, 22 de mayo de 2018 13:51
  • Si la idea es que parametrices la sentencia:

    SqlCommand cmd = new SqlCommand("INSERT INTO ... , (@diferenciaMoneda) ... )", con2);

    cmd.Parameters.AddWithValue("@diferenciaMoneda", decimal.Parse(txtDiferenciaMoneda.Text, ... ));

    En el decimal.Parse puedes agregarle parametros tales como NumberStyles.Any para indicar lo que quieres aceptar en el Text.

    Por supuesto, esto hay que repetirlo para todos los parametros que ahora tienes concatenados.

    martes, 22 de mayo de 2018 16:10
  • Muchas gracias por sus respuestas amigos funciono muy bien

    Alberto gracias por tu aclaración en como debe ser las cosas para la próxima ya se como debo trabajar, gracias 

    dejo el código por si a alguien un día lo necesita.

    con2.Close();
                            con2.Open();
                            SqlCommand cmd = new SqlCommand("INSERT INTO Cuadre (Cua_Fecha, Cua_Hora, Cua_Usuario, Cua_Caja, Cua_DolarC, Cua_Franco, Cua_Euro, Cua_Libra, Cua_Yen, Cua_DolarE, Cua_Peso, Cua_DiferenciaDolarC)values(('" + this.TxtFecha.Text + "'), CAST(GETDATE() AS TIME), ('" + this.LblUsuario.Text + "'), ('" + this.DdlCaja.Text + "'), ('" + this.TxtNombreDC.Text + "'), ('" + this.TxtNombreFS.Text + "'), ('" + this.TxtNombreEO.Text + "'), ('" + this.TxtNombreLE.Text + "'), ('" + this.TxtNombreYJ.Text + "'), ('" + this.TxtNombreDE.Text + "'), ('" + this.TxtNombrePD.Text + "'), (" + this.TxtDiferenciaMonedaDC.Text.Replace(",", "") + "))", con2);
                            cmd.ExecuteNonQuery();

                            ImgBarras.ImageUrl = "~/Imagenes/BarraVerde.png";
                            LblMensajes.Text = "Registro Guardado Exitosamente";

                            DdlCaja.Enabled = false;
                            Calendario.Enabled = false;

                            TxtNombreDC.ReadOnly = true;
                            TxtNombreFS.ReadOnly = true;
                            TxtNombreEO.ReadOnly = true;
                            TxtNombreLE.ReadOnly = true;
                            TxtNombreYJ.ReadOnly = true;
                            TxtNombreDE.ReadOnly = true;
                            TxtNombrePD.ReadOnly = true;

                            ImageButtonCancelar.Enabled = false;
                            ImageButtonCuadre.Enabled = false;
                            ImageButtonAceptar.Enabled = false;
                            ImgeButtonNuevo.Enabled = true;
                            ImageButtonImprimir.Enabled = true;
                        
                            con2.Close();

    jueves, 24 de mayo de 2018 10:22