可以筛选日期,但不能筛选日期时间

本文关键字:筛选 日期 时间 但不能 | 更新日期: 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上插入数据时也可以使用相同的技巧。