Usuario
Problema al filtrar con dateTimePicker

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
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
-
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(); } }
- Propuesto como respuesta By AlaN jueves, 26 de abril de 2012 13:39
-
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
-
-
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 -
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?
-
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