none
Problema al filtrar con dateTimePicker RRS feed

  • Pregunta

  • Hola soy nuevo en esto de C#  por lo que pregunto lo sig. Tengo que hacer una consulta de una Base de Datos de Acces pero tengo que filtrarla por dos fechas (desde y hasta ) esto lo he hecho con dos “datetimepicker” pero no logro hacer que filtre. Como le hago.

    Este es el query que uso el cual funciona perfecto.

    Conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Asistencia\ATT2000.mdb";

                    Qry = @"SELECT USERINFO.SSN,USERINFO.BADGENUMBER, USERINFO.NAME, USERINFO.ZIP, DEPARTMENTS.DEPTID, DEPARTMENTS.DEPTNAME, CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE

    FROM (USERINFO INNER JOIN DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID) INNER JOIN CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID

    WHERE (((DEPARTMENTS.DEPTID)=" + intIdDepto + ")) And (((CHECKINOUT.CHECKTIME)>#1/1/2012 5:0:0# And (CHECKINOUT.CHECKTIME)<#1/6/2012 5:59:1#)) ORDER BY USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME";

     

    Funciona bien pero el rango de fecha es constante (((CHECKINOUT.CHECKTIME)>#1/1/2012 5:0:0# And (CHECKINOUT.CHECKTIME)<#1/6/2012 5:59:1#))

    lo que requiero cambiar es la parte de #1/6/2012 2:59:1# por el valor que contengan los "dateTimePicker"

    GRACIAS

    jueves, 26 de abril de 2012 0:07

Todas las respuestas

  • Yo te suguiero la siguiente:

    Utilizar la siguiente SQL (de paso te la he parametrizado para evitar inyección de código, reutilización del plan de ejecución, ...)

    SELECT 
    	USERINFO.SSN,
    	USERINFO.BADGENUMBER, 
    	USERINFO.NAME, 
    	USERINFO.ZIP, 
    	DEPARTMENTS.DEPTID, 
    	DEPARTMENTS.DEPTNAME, 
    	CHECKINOUT.CHECKTIME, 
    	CHECKINOUT.CHECKTYPE
    FROM 
    	USERINFO INNER JOIN 
    	DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID INNER JOIN 
    	CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID
    WHERE 
    	(DEPARTMENTS.DEPTID=@depId) And 
    	(CHECKINOUT.CHECKTIME>@date1) And 
    	(CHECKINOUT.CHECKTIME<@date2) 
    ORDER BY USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME

    y añadiria los siguies parametros a la consulta

    using (SqlConnection cnn = new SqlConnection("connection string"))
    {
    		var query = "SELECT ...";
    
    	using (SqlCommand cmd = new SqlCommand(query, cnn))
    	{
    		cmd.Parameters.Add("@depId", SqlDbType.Int).Value = intIdDepto;
    		cmd.Parameters.Add("@date1", SqlDbType.DateTime).Value = datepicker1.SelectedDate;
    		cmd.Parameters.Add("@date2", SqlDbType.DateTime).Value = datepicker2.SelectedDate;
    
    		...
    	}
    }
    Espero haberte ayudado


    Xavi Paper

    jueves, 26 de abril de 2012 0:23
  • Umm, Xavi, creo que la pregunta va más por Access que por SqlServer. Pero siguiendo tu planteamiento sobre el uso de parámetros en la consulta el código quedaría algo así

    Conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Asistencia\ATT2000.mdb";
    Qry = @"SELECT USERINFO.SSN,USERINFO.BADGENUMBER, USERINFO.NAME, USERINFO.ZIP, DEPARTMENTS.DEPTID, DEPARTMENTS.DEPTNAME, CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE " +
           "FROM USERINFO " +
           "INNER JOIN DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID " +
           "INNER JOIN CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID " +
           "WHERE (DEPARTMENTS.DEPTID = ? And CHECKINOUT.CHECKTIME > ? And CHECKINOUT.CHECKTIME < ?) "+
           "ORDER BY USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME";
     
    
    using (OleDbConnection connection = new OleDbConnection(Conn))
    {
      connection.Open();
      
      using (OleDbCommand command = new OleDbCommand(Qry, connection)) 
      {
        command.Parameters.Add(intIdDepto); //El orden de los parámetros es importante
        command.Parameters.Add(datepicker1.SelectedDate;);
        command.Parameters.Add(datepicker2.SelectedDate;);
    
        command.ExecuteNonQuery();
      }
    }


    Atentamente, Sergio.

    Blog
    Twitter

    • Propuesto como respuesta By AlaN jueves, 26 de abril de 2012 13:39
    jueves, 26 de abril de 2012 7:45
  • Hola.

    Yo pondria el filtro con un Between y no me gusta concatenar tanto :P, mejor la usaria asi:

    Conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Asistencia\ATT2000.mdb";
    SQL= @"SELECT USERINFO.SSN,USERINFO.BADGENUMBER, USERINFO.NAME, USERINFO.ZIP, DEPARTMENTS.DEPTID, DEPARTMENTS.DEPTNAME, CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE
           FROM USERINFO
           INNER JOIN DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID
           INNER JOIN CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID
           WHERE (DEPARTMENTS.DEPTID = ? And CHECKINOUT.CHECKTIME BETWEEN ? And ?)
           ORDER BY USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME";
     
    
    using (OleDbConnection connection = new OleDbConnection(Conn))
    {
      
     
      OleDbCommand command = new OleDbCommand(Qry, connection);
      
      command.Parameters.AddWithValue("?",intIdDepto);
      command.Parameters.AddWithValue("?",datepicker1.Value);
      command.Parameters.AddWithValue("?",datepicker2.Value);
      connection.Open();
      command.ExecuteReader();
    
      //
      //Aqui hacer con los resultados que quieras
      //puedes usar un DataReader, como OleDbDataReader dr = command.ExecuteReader();
      //  
      connection.Close();
    }


    Pd: Luego del reader hace con la info lo que quiera ;).

    Saludos.




    • Editado By AlaN jueves, 26 de abril de 2012 22:11
    jueves, 26 de abril de 2012 13:42
  • Gracias por las respuestas, probare para ver cual es el que se adapta a lo que requiero.

    Muchas Gracias

    jueves, 26 de abril de 2012 21:17
  • Despues de tanto batallar encontre lasolucion, la comparto con ustedes por si hay quien se encuentre con el mismo problema.

    public String Conn, Qry,strFecha1,strFecha2;
    
    
    Conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Asistencia\ATT2000.mdb";
                    Qry = @"SELECT USERINFO.SSN,USERINFO.BADGENUMBER, USERINFO.NAME, USERINFO.ZIP, DEPARTMENTS.DEPTID, DEPARTMENTS.DEPTNAME, CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE
    FROM (USERINFO INNER JOIN DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID) INNER JOIN CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID
    WHERE (((DEPARTMENTS.DEPTID)=" + intIdDepto + ")) And (((CHECKINOUT.CHECKTIME)> #" + strFecha1 + " 5:0:0# And (CHECKINOUT.CHECKTIME)<#"+strFecha2 +" 22:59:00#)) ORDER BY USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME";
    
    
     private void hora1_ValueChanged(object sender, EventArgs e)
            {
                strFecha1 = this.hora1.Value.ToShortDateString();
    
            }
    
            private void hora2_ValueChanged(object sender, EventArgs e)
            {
                strFecha2 = this.hora2.Value.ToShortDateString();
            }
    

    Gracias y Suerte

    viernes, 27 de abril de 2012 0:27
  • Hola, es una solución, pero concatenar cadenas de caracteres no trae nada bueno. Si lo estás haciendo ahí, seguramente lo haras tambien en algun inicio de sesión y quedarás expuesto a ataques por Sql Injection.

    http://smarrerof.blogspot.com.es/2012/04/introduccion-al-sql-injection-en-sql.html

    Eso si contar que estás jugando con pasar horas a string. ¿Te has planteado que ocurre si instalas tu programa en un máquina donde el sistema operativo esté en inglés?


    Atentamente, Sergio.

    Blog
    Twitter

    viernes, 27 de abril de 2012 5:46
  • Correcto sergiomf,

    Yo evitaria siempe concatenar por problemas de seguiridad como bien dices, así como evitar utilizar strings (con el contenido de la fecha) por temas de formato  (nosotros tuvimos muchos problemas cuando intentamos subir una aplicación a azure donde el formato era MM/DD/YYYY por temas de estos).

    Yo recoiendo: parametrizar, usar el formato DateTime, usar usings, utilizar var, crear el command desde la conexión, ...

    Aquí va un ejemplo:

    var Conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Asistencia\ATT2000.mdb";
    var Qry = @"
    	SELECT USERINFO.SSN,USERINFO.BADGENUMBER, USERINFO.NAME, USERINFO.ZIP, DEPARTMENTS.DEPTID, DEPARTMENTS.DEPTNAME, CHECKINOUT.CHECKTIME, CHECKINOUT.CHECKTYPE
    	FROM 
    		USERINFO INNER JOIN 
    		DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID INNER JOIN 
    		CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID
    	WHERE 
    		(DEPARTMENTS.DEPTID = ?) And 
    		(CHECKINOUT.CHECKTIME) > ?) And 
    		(CHECKINOUT.CHECKTIME) < =)
    	ORDER BY USERINFO.BADGENUMBER, CHECKINOUT.CHECKTIME
    ";
    
    
    using (var connection = new OleDbConnection(Conn))
    {
    	connection.Open();
     
    	using (var command = connection.CreateCommand())
    	{
    		command.CommandText = query;
    
    		command.Parameters.Add(intIdDepto); //El orden de los parámetros es importante
    		command.Parameters.Add(datepicker1.Value.Date.Add(new TimeSpan(5, 0, 0));
    		command.Parameters.Add(datepicker2.Value.Date.Add(new TimeSpan(22,59,0));
    
    		command.ExecuteReader();
    
    		...
    	}
    // connection.Close(); Esto no es necesario al estar en el using
    }
    

    Salu2


    Xavi Paper

    viernes, 27 de abril de 2012 7:25