簡體   English   中英

在 SQL 查詢的 BETWEEN 子句中使用 Excel 單元格中的日期

[英]Use date in Excel cell in BETWEEN clause in SQL query

(1) 表DB-Fiddle

CREATE TABLE logistics (
    id int primary key,
    Product VARCHAR(255),
    insert_timestamp Date
);

INSERT INTO logistics
(id, product, insert_timestamp
)
VALUES 
("1", "Product_A", "2020-02-24 18:15:48"),
("2", "Product_B", "2020-02-24 20:30:17"),
("3", "Product_C", "2020-02-24 23:54:58"),
("4", "Product_D", "2020-02-25 08:09:30"),
("5", "Product_E", "2020-02-25 10:17:15");

(2) VBA
Cell B1 = 2020-02-24Cell B1 = 2020-02-24

Sub Get_Data()

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim dateVar As Date

    Set conn = New ADODB.Connection
    conn.ConnectionString = "DRIVER={MySQL ODBC 5.1 Driver}; SERVER=localhost; DATABASE=bi; UID=username; PWD=password; OPTION=3"
    conn.Open

                strSQL = " SELECT " & _
                            " cID " & _
                            " FROM logistics " & _
                            " WHERE DATE(insert_timestamp) BETWEEN """ & Format(Sheet1.Range("B1").Value, "YYYY-MM-DD") & "00:00:00" & """ " & _
                            " AND """ & Format(Sheet1.Range("B1").Value, "YYYY-MM-DD") & "23:59:59" & """ " & _
                            " GROUP BY 1 "


    Set rs = New ADODB.Recordset
    rs.Open strSQL, conn, adOpenStatic

    Sheet1.Range("A1").CopyFromRecordset rs

    rs.Close
    conn.Close

End Sub

我想在VBA中運行一個查詢,該查詢在WHERE子句的BETWEEN語句中使用Cell B1的日期。
當我在VBA之外運行此查詢時,它可以完美運行:

SELECT
Product
FROM logistics
WHERE DATE(insert_timestamp) BETWEEN "2020-02-24 00:00:00" AND "2020-02-24 23:59:59";

有一次,我在VBA運行它,它不會給我一個錯誤,但它也不會給我任何結果。
我認為這個問題是由我在strSQL中的sqlVBA組合引起的。

我必須如何更改VBA才能使其工作?

與其將日期或字符串等值格式化到 SQL 命令中,不如使用ADODB.Parameter - 在這種情況下,驅動程序將為您完成所有工作。 您不必關心字符串周圍的引號、格式化日期以便數據庫正確理解它(這在很大程度上取決於數據庫、區域設置等)。 此外,它還可以防止 SQL 注入。 另外,查詢優化器可以做得更好,因為它每次都獲得相同的 SQL 命令並記住執行計划。

缺點:代碼獲取稍微復雜一些,因為您必須涉及ADODB.command對象。

在你的 SQL 語句中,你放了一個簡單的? 在你想要參數的地方。 你只需要注意數字和位置? 和參數匹配。

Dim Conn As New ADODB.Connection, cmd As New ADODB.Command, param As ADODB.Parameter, rs As ADODB.Recordset
Conn.Open "<your connection string>"
Set cmd.ActiveConnection = Conn
cmd.CommandText = "SELECT cID FROM logistics WHERE DATE(insert_timestamp) BETWEEN ? AND ? GROUP BY 1"

Set param = cmd.CreateParameter(, adDate, adParamInput, , Date)
cmd.Parameters.Append param
Set param = cmd.CreateParameter(, adDate, adParamInput, , Date + 1)
cmd.Parameters.Append param

Set rs = cmd.Execute
Debug.Print rs.Fields(0).Name, rs(0).Value

PS 對日期處理有點懶惰,如果您恰好在午夜有數據,您會得到太多數據。

您在日期和時間之間缺少一個空格...

打開您的 VBE 並調試打印公式以查看結果(確保您有即時窗口 [查看菜單/即時窗口)。

Sub test()
   Debug.Print Format(Sheet1.Range("B1").Value, "YYYY-MM-DD") & "23:59:59"
End Sub

結果2020-03-1123:59:59

只需在 DD 后添加空格如下

Format(Sheet1.Range("B1").Value, "YYYY-MM-DD ") & "23:59:59"

我知道你已經接受了一個答案,這是一個非常好的答案。 我只是把它留在這里作為一種替代方法,你可能會發現它在其他情況下也很有用:

Dim date_to_use As String

date_to_use = Format(Sheet1.Range("B1").Value, "YYYY-MM-DD")

strSQl = " SELECT " & _
            " cID " & _
            " FROM logistics " & _
            " WHERE DATE(insert_timestamp) BETWEEN '[date to use] 00:00:00'" & _
            " AND '[date to use] 23:59:59'" & _
            " GROUP BY 1 "

strSQl = Replace(strSQl, "[date to use]", date_to_use)

在使用之前以這種方式存儲B1的內容還允許您對其應用其他更改 - 以防萬一您想進一步清理它或減少使用 SQL 注入的機會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM