2015-04-02 50 views
1

我試圖用這個查詢時,「數據不匹配的標準SQL」,但我得到一個錯誤的標準使用日期

數據不匹配

Dat是MS裏面的Date列訪問數據庫。我想選擇列的總和命名爲Total每個命名之間的日期從datepickers拿起Pro行...

有這方面的帖子很多,但我的查詢是不同的,那麼那些

Dim DTST As String 
DTST = DateTimePicker1.Value.ToString 

Dim DTEn As String 
DTEn = DateTimePicker2.Value.ToString 

Dim Query1 As String = "SELECT SUM(Total) FROM [T500] WHERE Pro [email protected] AND Dat BETWEEN'" + DTST + "' AND '" + DTEn + "'" 

Dim cmd2 As OleDb.OleDbCommand = New OleDbCommand(Query1, dbCon) 
cmd2.Parameters.AddWithValue("@Pro", ComboBoxBP.SelectedItem.ToString) 
+0

嘿日期/時間格式專家!你爲什麼不使用'DTST'和'DTEn'的sql參數並讓框架完成它的工作?你有沒有想過' .ToString()'返回什麼?它是一個有效的ms訪問日期格式?本地化呢? – 2015-04-02 08:38:39

+0

這是一個有效的格式。我已經改變它來匹配我的數據庫中的格式。嘗試它沒有ToString,錯誤的同一圈,無論是語法錯誤,或數據不匹配:S – Taffs 2015-04-02 08:40:54

回答

2

我的編輯似乎爲c所以這裏是:

Dim DTST As String 
DTST = DateTimePicker1.Value.ToString("'#'yyyy'/'MM'/'dd'#'") 

Dim DTEn As String 
DTEn = DateTimePicker2.Value.ToString("'#'yyyy'/'MM'/'dd'#'") 

Dim Query1 As String = "SELECT SUM(Total) FROM [T500] WHERE Pro [email protected] AND Dat BETWEEN " + DTST + " AND " + DTEn + "" 
+0

這工作,謝謝。 – Taffs 2015-04-02 09:08:59

1

在Access中參數化的日期必須被包裹在#報價外(如果它裏面是一個文本日期,如#10/10 /到2015年#

Dim DTST As String 
DTST = DateTimePicker1.Value.ToString("'#'yyyy'/'MM'/'dd'#'") 

Dim DTEn As String 
DTEn = DateTimePicker2.Value.ToString("'#'yyyy'/'MM'/'dd'#'") 

Dim Query1 As String = "SELECT SUM(Total) FROM [T500] WHERE Pro [email protected] AND Dat BETWEEN " + DTST + " AND " + DTEn + "" 

Dim cmd2 As OleDb.OleDbCommand = New OleDbCommand(Query1, dbCon) 
cmd2.Parameters.AddWithValue("@Pro", ComboBoxBP.SelectedItem.ToString) 
+0

我曾嘗試用「#」之前,並得到語法錯誤...'附加信息:在查詢表達式中的日期中的語法錯誤'= @ Pro AND Dat BETWEEN#'4/1/2015 12:00:00 AM'#AND#'4/2/2015 12:00:00 AM''。 – Taffs 2015-04-02 08:18:01

+0

立即試用,ive改變了位置 – Matt 2015-04-02 08:24:18

+0

現在它說'數據類型不匹配':S這些錯誤一直在盤旋,無論我嘗試什麼...... – Taffs 2015-04-02 08:27:35

4

日期只是附加參數。你(和其他答案)這樣做的一個問題是,你正在將完美的DateTime變量轉換爲字符串。 MSAccess/OleDb通常會讓事情變得有意義,但這是不必要的,並且允許別的事情來解釋你的意圖通常是不可取的。

DB列必須實現爲Date類型,以便將數據視爲Dates(BETWEEN),但不需要「格式化」Date變量(永遠)。

Dim SQL = "SELECT SUM(Total) FROM [T500] WHERE Pro [email protected] AND Dat BETWEEN @dt1 AND @dt2" 


Using dbCon As OleDbCOnnection(GetConnection()), 
    cmd As New OleDbCommand(SQL, dbCon) 

    dbCon.Open 

    ' ToDO be sure SelectedItems.COunt >0 earlier 
    cmd2.Parameters.AddWithValue("@Pro", ComboBoxBP.SelectedItem.ToString) 
    cmd2.Parameters.AddWithValue("@dt1", DateTimePicker1.Value) 
    cmd2.Parameters.AddWithValue("@dt2", DateTimePicker2.Value) 

    Dim Total = cmd.ExecuteScalar() 
    ... 
End Using  ' close and dispose of Command and Connection objects 

正如你所看到的,您傳遞日期時間值,以它作爲任何其他參數,以及DTP的.Value屬性將很好地工作:

當他們做的另一個問題是處置命令和Connection對象的沒有任何按摩或處理。

以下是有關GetConnection() method和dbConnections一般信息的鏈接。


注意OleDB實際上並沒有使用命名參數(@Pro,@ DT1)。它們只是佔位符,您必須以與它們在SQL語句中出現的順序相同的順序排列AddWithValue。將參數指定爲「?」更常見,但有意義的參數有助於將正確的var映射到代碼中的正確參數。

最後,它不能與DateTimePicker發生,但將UI控件中的字符串粘在一起以使SQL可能導致SQL注入攻擊,應始終避免。使用參數的SQL通常更容易編碼,構建,讀取和維護。