可以筛选日期,但不能筛选日期时间
本文关键字:筛选 日期 时间 但不能 | 更新日期: 2023-09-27 18:29:08
我有一个应用程序,可以使用日期时间选择器根据日期筛选数据网格视图。我的数据库中的"日期"列是日期时间数据类型,因此它将包含存储在其中的日期和时间,但有些数据只有日期。我的问题是,我的日期时间选择器筛选器只能筛选日期=12:00:00 AM的数据。当我使用datatimepicker选择日期时,无法筛选那些包含时间以外的数据。我不知道出了什么问题。这是我的代码:
public trackInput()
{
InitializeComponent();
dataGridView1.Visible = false;
webBrowser1.Location = new Point(12, 141);
}
/*private void trackInput_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'trackingBMSDATADataSet.BRDATA' table. You can move, or remove it, as needed.
this.bRDATATableAdapter.Fill(this.trackingBMSDATADataSet.BRDATA);
}*/
private void trackBtn_Click(object sender, EventArgs e)
{
dataGridView1.Visible = true;
if (dataGridView1.Visible == true)
{
webBrowser1.Location = new Point(12, 397);
}
//DataTable dt = null;
string connoInput = textBox1.Text;
string conString = Properties.Settings.Default.BMSDATAConnectionString;
using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:'Documents and Settings'Administrator'My Documents'Visual Studio 2008'Projects'TrackCon'TrackCon'BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$"))
{
string Ids = "conno= '" + System.Text.RegularExpressions.Regex.Replace(textBox1.Text.Trim(), @"'s*'n's*", "' OR conno= '") + "'";
SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " +Ids, con);
SqlCeDataAdapter adap = new SqlCeDataAdapter(com);
DataSet set = new DataSet();
adap.Fill(set);
if (set.Tables.Count > 0)
{
bRDATABindingSource1.DataSource = set.Tables[0];
}
bRDATABindingSource1.Filter = null;
dataGridView1.DataSource = bRDATABindingSource1;
con.Close();
}
}
private void trackMPSbtn_Click(object sender, EventArgs e)
{
dataGridView1.Visible = true;
if (dataGridView1.Visible == true)
{
webBrowser1.Location = new Point(12, 397);
}
//DataTable dt = null;
//string connoInput = textBox1.Text;
string conString = Properties.Settings.Default.BMSDATAConnectionString;
using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:'Documents and Settings'Administrator'My Documents'Visual Studio 2008'Projects'TrackCon'TrackCon'BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$"))
{
dataGridView1.DataSource = bRDATABindingSource1;
string Ids = "cmpsno= '" + System.Text.RegularExpressions.Regex.Replace(textBox2.Text.Trim(), @"'s*'n's*", "' OR cmpsno= '") + "'";
con.Open();
SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " + Ids, con);
SqlCeDataAdapter adap = new SqlCeDataAdapter(com);
DataSet set = new DataSet();
adap.Fill(set);
if (set.Tables.Count > 0)
{
bRDATABindingSource1.DataSource = set.Tables[0];
}
bRDATABindingSource1.Filter = null;
dataGridView1.DataSource = bRDATABindingSource1;
con.Close();
}
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
bRDATABindingSource1.Filter = string.Format("dsysdate = #{0:d/M/yyyy HH:mm tt}#", dateTimePicker1.Value.ToLongDateString());
}
DateTimePicker有一个包含所选日期的属性Value。您应该使用此日期来形成如下查询:
where somedate >= datetimepicker.Value.Date
and somedate < datetimepicker.Value.Date.AddDays(1)
其中.Date仅返回DateTime的日期部分。要准备where子句,请将SqlCeCommand的where部分替换为
" where conno >= @startDate and conno < @endDate"
向SqlCeCommand 添加两个参数
com.Parameters.Add (new SqlCeParameter("@startDate", SqlDbType.DateTime,
textbox1.Value.Date));
com.Parameters.Add (new SqlCeParameter("@endDate", SqlDbType.DateTime,
textbox1.Value.Date.AddDays(1)));
用cmpsno做类似的练习。
更新:我完全错过了最后一个方法。
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
bRDATABindingSource1.Filter = string.Format("dsysdate >= '{0:yyyy-MM-dd}' AND dsysdate < '{1:yyyy-MM-dd}'", dateTimePicker1.Value, dateTimePicker1.Value.AddDays(1));
}
尝试解释:
由于dsysdate有一个时间组件,您需要筛选一个从午夜开始一直到第二天午夜的间隔-这是Value.AddDays(1)。不幸的是,我对筛选BindingSource不太了解,因为我主要在数据库级别进行筛选,因此是第一个代码。您可能需要重写dateTimePicker1_ValueChanged以从数据库中检索数据,而不是在内存中进行筛选;由于索引的原因,使用较大的表会有回报。
说到这里,您可能会考虑以不同的方式构建代码。这样的任务通常是通过一种方法来完成的,该方法检查筛选控件,构建查询并执行它,从而消除重复的代码,并使您能够同时按多个条件进行筛选。方法在筛选控件的内容更改时调用。
我必须发表以下几点评论:
第一:永远不要把查询和文本串在一起。即使您试图清理输入,这也会受到SQL注入的影响。请改用存储过程或参数化查询:它们完全不受SQL注入的影响。
第二:使用参数,因为您可以简单地传递原始形式的值,而不是将它们转换为文本。这将消除部分问题。可以使用存储过程或参数化查询。
2nd&1/2:使用参数还有其他原因,这与性能有关。
第三:按日期时间过滤可能会起作用,但你不能保证。你希望用户能够按精确的日期时间过滤吗,包括秒和秒的分数?我认为这不是个好主意。请重新设计一下,或者解释一下你想做什么。看起来没有什么意义。也许在将日期存储到数据库之前,您应该将其"四舍五入"到秒或分钟。你应该考虑一下日期时间并不准确。它的工作方式有点像浮点运算,所以您可以直接比较这些值而不会遇到麻烦。也就是说,我等待你的意见来帮助你改进你的设计。
添加了:正如你所说的时间部分并不重要,你可以在插入或比较时删除它(同时将日期时间列与参数进行比较),使用以下"技巧":
SELECT (CAST(FLOOR(CAST(YourDateTimeColumn as FLOAT)) AS DateTime))
日期在内部存储为从基准日期算起的天数。小数部分表示一天的小数(hh:mm:ss…)。因此,如果去掉小数,则只保留日期部分,并且可以安全地将其与给定日期进行比较。
如果不需要时间部分:如果使用的是SQL Server 2008或更高版本,则可以为列使用DATE类型(如果不需要存储时间)。或者,在以前版本的SQL Server上插入数据时也可以使用相同的技巧。