2012-03-28 173 views
1

我有一個應用程序,可以使用datetimepicker基於日期過濾datagridview。我的數據庫中的「日期」列是日期時間數據類型,因此它將包含存儲在其中的日期和時間,但有一些數據只有日期。我的問題是我的datetimepicker過濾器只能用date = 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()); 
    } 

回答

1

DateTimePicker具有包含選定日期的屬性值。你應該使用這個日期,形成一個查詢看起來像這樣:

where somedate >= datetimepicker.Value.Date 
    and somedate < datetimepicker.Value.Date.AddDays(1) 

其中.Date只返回日期時間的日期部分。爲了準備where子句中,替換其中具有

" where conno >= @startDate and conno < @endDate" 

SqlCeCommand的部分添加兩個參數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)。不幸的是,我對Filter BindingSource的過濾知之甚少,因爲我主要是在數據庫級別進行過濾,因此我首先進行了過濾。您可能需要重寫dateTimePicker1_ValueChanged以從數據庫中檢索數據,而不是在內存中進行篩選;當由於索引而使用較大的表格時,它會得到回報。說到這一點,你可能會考慮以不同的方式構建你的代碼。這樣的任務通常是通過一種方法來完成的,該方法檢查過濾控件,構建查詢並執行它,從而消除重複的代碼並允許您一次過濾多個條件。方法比過濾控件的內容更改時被調用。

+0

對不起尼古拉,但我不太明白,你能解釋一下嗎? – 2012-03-28 02:07:41

+0

@ shahrul1509請參閱更新 – 2012-03-28 07:36:21

+0

感謝您的建議@尼古拉。 textboxt實際上是一個文本框。我的應用程序的總功能實際上是它有兩個過濾器。一個是按ID過濾。用戶可以輸入ID,系統將顯示ID信息。然後用戶可以通過使用datetimepicker選擇日期來進一步過濾該信息。我的問題在於日期過濾器。文本框過濾器工作正常。:) – 2012-03-28 07:40:19

0

我有幾點意見:

1:串聯文本永遠不要編寫查詢。即使您嘗試清理輸入,也會受到SQL注入的影響。改爲使用存儲過程或參數化查詢:它們完全免疫SQL注入。

第二:使用參數,因爲您可以簡單地傳遞原始形式的值,而不是將它們轉換爲文本。這將消除部分問題。您可以使用存儲過程或參數化查詢。

2nd & 1/2:還有其他原因使用參數,這與性能有關。

第3:可能按日期時間過濾將起作用,但您無法保證。您是否希望用戶能夠按照確切的日期時間進行過濾,包括秒和幾分之一秒?我認爲這不是一個好主意。請重新設計它或解釋你想要做什麼。它看起來沒有多少意義。也許你應該在將日期存儲在數據庫之前將日期「舍入」到幾秒或幾分鐘。你應該考慮日期時間不準確。它的工作原理有點像浮點數,所以你可以直接比較這些數值而不會有問題。也就是說,我等待您的意見來幫助您改進設計。

增加: 至於你說的部分時間並不重要,你可以插入刪除,或在比較(在比較與參數datetime列),使用這個「絕招」:

SELECT (CAST(FLOOR(CAST(YourDateTimeColumn as FLOAT)) AS DateTime)) 

日期在內部存儲爲從基準日起的天數。小數部分表示一天中的小數部分(hh:mm:ss ...)。所以,如果你擺脫了小數,你只保留日期部分,並且可以安全地將它與給定日期進行比較。

如果您不需要時間部分:如果您使用的是SQL Server 2008或更高版本,則可以對列使用DATE類型(如果您不需要存儲時間)。或者,您可以在將數據插入以前版本的SQL Server時使用相同的技巧。

+0

感謝提示。我會牢記並改進它。我在c#環境中仍然是新手,仍然在努力提高自己。對於第三條評論,當然用戶不需要插入時間的確切細節。用戶只需要選擇一個日期,datagridview將根據選擇的日期進行過濾。但正如我所說,在選擇日期之後,過濾器只能檢測到包含time = 12:00:00 AM的數據。那些含有其他時間的數據不能被檢測到被過濾。 – 2012-03-28 01:35:51

+0

請看看如何擺脫datetime部分。還有其他一些方法,但我認爲這是更快。 – JotaBe 2012-03-28 02:08:14

+0

對不起,理論上我理解它是如何工作的,但我不太清楚我需要放置哪些代碼部分。我儘量把它放在這兒: '私人無效dateTimePicker1_ValueChanged(對象發件人,EventArgs的) {SqlCeCommand釐米= 新SqlCeCommand( 「SELECT(CAST(FLOOR(CAST(dsysdate爲FLOAT) 爲DATETIME))FROM BRDATA」 ); bRDATABindingSource1.Filter = 的String.Format ( 「dsysdate =#{0:DD/MM/YYYY}#」,dateTimePicker1.Value.ToLongDateString());} ' 但是當我運行,所述 – 2012-03-28 02:23:54