简体   繁体   English

在 SQL 查询的 BETWEEN 子句中使用 Excel 单元格中的日期

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

(1) Table DB-Fiddle (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 (2) VBA
Value in Cell B1 = 2020-02-24 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

I want to run a query within the VBA that uses the date in Cell B1 within the BETWEEN statement in the WHERE clause.我想在VBA中运行一个查询,该查询在WHERE子句的BETWEEN语句中使用Cell B1的日期。
When I run this query outside of the VBA it works perfectly:当我在VBA之外运行此查询时,它可以完美运行:

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

Once, I run it in the VBA it does not give me an error but it also does not give me any result.有一次,我在VBA运行它,它不会给我一个错误,但它也不会给我任何结果。
I assume the issue is caused by my combination of the sql and the VBA in the strSQL .我认为这个问题是由我在strSQL中的sqlVBA组合引起的。

How do I have to change the VBA to make it work?我必须如何更改VBA才能使其工作?

Instead of formatting values like dates or strings into the SQL command, it is much better to use ADODB.Parameter - in that case the driver will do all the work for you.与其将日期或字符串等值格式化到 SQL 命令中,不如使用ADODB.Parameter - 在这种情况下,驱动程序将为您完成所有工作。 You don't have to take care about quotes around a string, formatting a date so that the database understands it correctly (which is highly depending on database, regional settings and so on).您不必关心字符串周围的引号、格式化日期以便数据库正确理解它(这在很大程度上取决于数据库、区域设置等)。 Plus it is a protection against SQL injection.此外,它还可以防止 SQL 注入。 Plus, the query optimizer can do it's job much better because it gets the same SQL command every time and remembers the execution plan.另外,查询优化器可以做得更好,因为它每次都获得相同的 SQL 命令并记住执行计划。

Drawback: code get's slightly more complicated because you have to involve a ADODB.command object.缺点:代码获取稍微复杂一些,因为您必须涉及ADODB.command对象。

In your SQL statement, you put a simple ?在你的 SQL 语句中,你放了一个简单的? at the place where you want to have a parameter.在你想要参数的地方。 You just have to take care that the numbers and the position of ?你只需要注意数字和位置? and parameters matches.和参数匹配。

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 Was a little lazy for the date handling, if you have data exactly at midnight, you would get too much data. PS 对日期处理有点懒惰,如果您恰好在午夜有数据,您会得到太多数据。

you are missing a space between the date and the time...您在日期和时间之间缺少一个空格...

Open your VBE and debug print the formula to see the result (maker sure you have the immediate window [view menu / Immediate window).打开您的 VBE 并调试打印公式以查看结果(确保您有即时窗口 [查看菜单/即时窗口)。

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

result 2020-03-1123:59:59结果2020-03-1123:59:59

Just can add the space after the DD as follow只需在 DD 后添加空格如下

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

I know you've accepted an answer and it's a perfectly good one.我知道你已经接受了一个答案,这是一个非常好的答案。 I'm just leaving this here as an alternative method which you might find useful in other cases too:我只是把它留在这里作为一种替代方法,你可能会发现它在其他情况下也很有用:

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)

Storing the contents of B1 in this way before using it also allows you to apply other changes to it - just in case you wanted to clean it up further or reduce the chances of SQL injection being used..在使用之前以这种方式存储B1的内容还允许您对其应用其他更改 - 以防万一您想进一步清理它或减少使用 SQL 注入的机会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM