none
Hola tengo el error que dice System.Data.SqlClient.SqlException error converting data type varchar to datetime. Ayudaaa! RRS feed

  • Pregunta

  • Aqui dejo el codigo, el error creo q es en el metodo guardar:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace Sistema_facturacion_2020_1
    {
        public partial class frmEmpleados : Form
        {
            public frmEmpleados()
            {
                InitializeComponent();
            }

            

            private void materialSingleLineTextField6_Click(object sender, EventArgs e)
            {

            }

            private void textBox1_TextChanged(object sender, EventArgs e)
            {

            }

            private void materialRaisedButton2_Click(object sender, EventArgs e)
            {
                DialogResult Rta;
                Rta = MessageBox.Show("Desea Salir De La Edición ?", "MENSAJE DE ADVERTENCIA", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                if (Rta == DialogResult.OK)
                {
                    this.Close();
                }
              
            }
           
            private void LLENAR_GRID()
            {
                DataTable dt = new DataTable();
                Acceso_datos Acceso = new Acceso_datos();
                dt = Acceso.cargartabla("TBLEMPLEADO", "");
                dgEmpleados.DataSource = dt;

                dt = Acceso.cargartabla("TBLROLES", "");
                cboRol.DataSource = dt;
                cboRol.DisplayMember = "StrDescripcion";
                cboRol.ValueMember = "IdRolEmpleado";
            }
            private Boolean VALIDAR()
            {
                Boolean errorCampos = true;
                if (txtNombre.Text == string.Empty)
                {
                    MensajeError.SetError(txtNombre, "Debe Ingresar El Nombre Del Empleado");
                    errorCampos = false;
                }
                else
                {
                    MensajeError.SetError(txtNombre, "");
                }
                if (txtDocumento.Text == "")
                {
                    MensajeError.SetError(txtDocumento, "Debe Ingresar El Documento");
                    txtDocumento.Focus();
                    errorCampos = false;
                }
                else
                {
                    MensajeError.SetError(txtDocumento, "");
                }
                if(!esNumerico(txtDocumento.Text))
                {
                    MensajeError.SetError(txtDocumento, "El Documento Debe Ser Numerico");
                    txtDocumento.Focus();
                    return false;
                }
                MensajeError.SetError(txtDocumento, "");
                return errorCampos;
            }

            private bool esNumerico(string num)
            {
                try
                {
                    double x = Convert.ToDouble(num);
                    return true;
                }
                catch(Exception)
                {
                    return false;
                }
            }
            // ingreso, retiro y actualizacion de informacion en la bd


            public bool Guardar()
            {
                Boolean actualizado = false;
                if (VALIDAR())
                {
                    try
                    {
                        Acceso_datos Acceso = new Acceso_datos();
                        DateTime dtmin = DateTime.Parse(dtmIngreso.Text);
                        DateTime dtmre = DateTime.Parse(dtmRetiro.Text);

                        string sentencia = $"Exec actualizar_Empleado {txtIdEmpleado}, '{txtNombre.Text}', {txtDocumento.Text}, '{txtDireccion.Text}', '{txtTelefono.Text}', '{txtEmail.Text}',{cboRol.SelectedValue}, '{dtmin}','{dtmre}','{txtDatosAdiccionales.Text}' ,'{DateTime.Now.ToShortDateString()}','Alexis'";
                        MessageBox.Show(Acceso.EjecutarComando(sentencia));
                        LLENAR_GRID();
                        actualizado = true;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Falló La Inserción: " + ex);
                        actualizado = false;
                    }
                }
                
                   
                  return actualizado;
            }

            public void Eliminar()
            {
                Acceso_datos Acceso = new Acceso_datos();
                string sentencia = $"Exec Eliminar_empleado '{Convert.ToInt32(txtIdEmpleado.Text)}'";
                MessageBox.Show(Acceso.EjecutarComando(sentencia));
                LLENAR_GRID(); // ACTUALIZAMOS EL GRID- SE REFLEJA EL CAMBIO
                Nuevo();
            }


            // LIMPIAMOS LOS CAMPOS DEL FORMULARIO:

            public void Nuevo()
            {
                txtIdEmpleado.Text = "";
                txtNombre.Text = "";
                txtDocumento.Text = "";
                txtDireccion.Text = "";
                txtTelefono.Text = "";
                txtEmail.Text = "";
                cboRol.SelectedIndex = 0;
                dtmIngreso.Value = DateTime.Now;
                dtmRetiro.Value = Convert.ToDateTime("01/01/1990");
                txtDatosAdiccionales.Text = "";
            }
                
    //fin de  actualizacion de  la informacion
              
               


            private void frmEmpleados_Load(object sender, EventArgs e)
            {
                LLENAR_GRID();

            


            }
            

            private void groupBox2_Enter(object sender, EventArgs e)
            {

            }

            private void lblFechaIngreso_Click(object sender, EventArgs e)
            {

            }

            private void dgEmpleados_CellContentClick(object sender, DataGridViewCellEventArgs e)
            {

            }

            private void dgEmpleados_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
            {
                /* Cargamos el contenido de la fila del grid en los campos del formulario
                 * la informacion se carga en los campos cada vez que damos clic en 
                 * una fila del grid
                 */
                int posActual = 0;
                posActual = dgEmpleados.CurrentRow.Index;
                txtIdEmpleado.Text = dgEmpleados[0, posActual].Value.ToString();
                txtNombre.Text= dgEmpleados[1, posActual].Value.ToString();
                txtDocumento.Text = dgEmpleados[2, posActual].Value.ToString();
                txtDireccion.Text = dgEmpleados[3, posActual].Value.ToString();
                txtTelefono.Text = dgEmpleados[4, posActual].Value.ToString();
                txtEmail.Text = dgEmpleados[5, posActual].Value.ToString();
                cboRol.SelectedValue = Convert.ToInt16(dgEmpleados[6, posActual].Value.ToString());
                dtmIngreso.Value = Convert.ToDateTime(dgEmpleados[7, posActual].Value.ToString());

                if (dgEmpleados[8, posActual].Value.ToString() != "")
                {
                    dtmRetiro.Value = Convert.ToDateTime(dgEmpleados[8, posActual].Value.ToString());
                }
                else
                {
                    dtmRetiro.Value = Convert.ToDateTime("01/01/1900");
                }


                txtDatosAdiccionales.Text = dgEmpleados[9, posActual].Value.ToString();



            }

            private void btnEliminar_Click(object sender, EventArgs e)
            {
                Eliminar();
            }

            private void btnNuevo_Click(object sender, EventArgs e)
            {
                Guardar();
            }

            private void btnActualizar_Click(object sender, EventArgs e)
            {
                Nuevo();
            }

            private void btnBuscar_Click(object sender, EventArgs e)
            {
                Acceso_datos Acceso = new Acceso_datos();
                if (txtBuscar.Text != "")
                {
                    string sentencia = $"select * from TBLEMPLEADO where strNombre like '%{txtBuscar.Text}%'";
                    dgEmpleados.DataSource = Acceso.EjecutarComandoDatos(sentencia);
                    txtBuscar.Text = "";
                }
                else
                {
                    LLENAR_GRID();
                }
            }
        }
    }

    jueves, 19 de marzo de 2020 2:51

Respuestas

  • Probablemente el error esté en el sitio en donde llamas al procedimiento almacenado "actualizar_empleado" pasándole como parámetro '{DateTime.Now.ToShortDateString()}'.

    Al llamar a ToShortDateString, se va a convertir la fecha en una cadena de texto con el formato que tengas configurado en el Panel de Control, tal como por ejemplo dia/mes/año. Si el procedimiento almacenado espera un valor de tipo DATETIME, entonces va a intentar realizar una conversión implícita desde la cadena que le pasas entre comillas (que es un tipo VARCHAR) al tipo que requiere, que es un DATETIME. Pero en el lenguaje SQL, el formato de las fechas para que esa conversión pueda funcionar tiene que ser mes/dia/año o añomesdia. Si tu Panel de Control estaba configurado con otro formato, se produce un error como el que estás viendo.

    Aunque podrías meter algo de código en C# para cambiar el formato de la fecha, esa no es la solución ideal. La solución recomendada, que además te evitará muchos otros problemas adicionales como por ejemplo la vulnerabilidad ante ataques de inyección de SQL, es parametrizar las sentencias SQL. En lugar de meter los datos como string en el CommandText, se escribe un SqlCommand que usa Parameters, y los datos que quieres enviar al servidor se asignan directamente a cada parámetro. Esta asignación se hace sin convertir el tipo, es decir, al datetime le asignarías directamente un datetime, sin convertirlo en string. Y el sistema de parametrización ya sabe internamente hacer las conversiones necesarias para que al servidor le llegue el formato correcto, sin que tengas que preocuparte de cuál es ese formato.

    jueves, 19 de marzo de 2020 7:24
    Moderador

Todas las respuestas

  • Probablemente el error esté en el sitio en donde llamas al procedimiento almacenado "actualizar_empleado" pasándole como parámetro '{DateTime.Now.ToShortDateString()}'.

    Al llamar a ToShortDateString, se va a convertir la fecha en una cadena de texto con el formato que tengas configurado en el Panel de Control, tal como por ejemplo dia/mes/año. Si el procedimiento almacenado espera un valor de tipo DATETIME, entonces va a intentar realizar una conversión implícita desde la cadena que le pasas entre comillas (que es un tipo VARCHAR) al tipo que requiere, que es un DATETIME. Pero en el lenguaje SQL, el formato de las fechas para que esa conversión pueda funcionar tiene que ser mes/dia/año o añomesdia. Si tu Panel de Control estaba configurado con otro formato, se produce un error como el que estás viendo.

    Aunque podrías meter algo de código en C# para cambiar el formato de la fecha, esa no es la solución ideal. La solución recomendada, que además te evitará muchos otros problemas adicionales como por ejemplo la vulnerabilidad ante ataques de inyección de SQL, es parametrizar las sentencias SQL. En lugar de meter los datos como string en el CommandText, se escribe un SqlCommand que usa Parameters, y los datos que quieres enviar al servidor se asignan directamente a cada parámetro. Esta asignación se hace sin convertir el tipo, es decir, al datetime le asignarías directamente un datetime, sin convertirlo en string. Y el sistema de parametrización ya sabe internamente hacer las conversiones necesarias para que al servidor le llegue el formato correcto, sin que tengas que preocuparte de cuál es ese formato.

    jueves, 19 de marzo de 2020 7:24
    Moderador
  • hola

    No se ejecuta de esa forma un procedure, NUNCA se concatenan los valores en un string, tienes que usar parametros

    tu codigo deberia ser como esto

    public bool Guardar()
    {
    
    	if (!VALIDAR())
    		return;
    	
    	try
    	{
    		using (SqlConnection conn = new SqlConnection("connectionstring")) 
    		{ 
    
    			SqlCommand cmd = new SqlCommand("actualizar_Empleado", conn); 
    			cmd.CommandType = SqlCommandType.StoredProcedure; 
    
    			cmd.Parameters.AddWithValue("@IdEmpleado", Convert.ToInt32(txtIdEmpleado.Text)); 
    			cmd.Parameters.AddWithValue("@nombre", txtNombre.Text); 
    			cmd.Parameters.AddWithValue("@documento", Convert.ToInt32(txtDocumento.Text)); 
    			cmd.Parameters.AddWithValue("@direccion", txtDireccion.Text);
    			cmd.Parameters.AddWithValue("@telefono", txtTelefono.Text);
    			
    			//resto de los parametros
    			
    			cmd.ExecuteNonQuery(); 
    		} 
    				
    		
    		LLENAR_GRID();
    
    	}
    	catch (Exception ex)
    	{
    		MessageBox.Show("Falló La Inserción: " + ex.Message);
    	}
    	
    }

    No se que haces dentro de EjecutarComando() pero sino permite el uso de parametroe entonces sera mejor que no lo uses o debas adaptarlo

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    jueves, 19 de marzo de 2020 13:02
  • Gracias!!!
    viernes, 20 de marzo de 2020 2:01