【问题标题】:Passing Date variables in vba to sql statement将vba中的日期变量传递给sql语句
【发布时间】:2015-08-07 07:54:15
【问题描述】:

我查看了已经发布的各种不同场景,但似乎没有一个解决方案能带来任何乐趣。 我正在尝试将日期变量传递到 sql select 语句中,但我得到一个关于转换为日期/时间的错误,或者变量定义不正确,即语法不正确。 这同样适用于变量“contractNumber”,但我希望日期变量完成后,同样适用于“contractNumber”变量。 我试过用 "" / "& / #"" & 包围变量,但这些组合似乎都不起作用....

我使用的代码如下,“控制”表中的日期是标准英国日期 - DD/MM/YYYY

Sub MEHT()

Dim startdate As Date
Dim enddate As Date
Dim contractNumber As String

startdate = Sheets("Control").Range("K8").Value
enddate = Sheets("Control").Range("K10").Value
contractNumber = Sheets("Control").Range("K13").Value

Call ConnectSqlServer

End Sub

Sub ConnectSqlServer()

    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sConnString As String

    ' Create the connection string.
    sConnString = "Provider=SQLOLEDB;Data Source=NT124431\DW;" & _
                  "Initial Catalog=hdw2;" & _
                  "Integrated Security=SSPI;"


    ' Create the Connection and Recordset objects.
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset

    ' Open the connection and execute.
    conn.Open sConnString
    Set rs = conn.Execute("SELECT SAF.Tracking_Number, ORH.CUSTOMER_PO_NUMBER,MAX(DOC.DOCUMENT_NUMBER),DOC.DOCUMENT_DATE_KEY,SAF.ITEM_NUMBER,  MAX(ITM.HOMECRAFT_ITEM_NUMBER), " _
        & "MAX(ITM.ITEM_DESCR),MAX(ADR.ADDR_NAME),MAX(ADR.ADDR1),MAX(ADR.ZIP_5_KEY),SUM(SAF.QUANTITY_SOLD),SUM(SAF.EXTENDED_AMOUNT) " _
        & ",SUM(SAF.EXTENDED_AMOUNT) / SUM(SAF.QUANTITY_SOLD) FROM SALES_FACT SAF  JOIN LU_CUSTOMER_TBL CUS ON SAF.CUSTOMER_KEY = CUS.CUSTOMER_KEY " _
        & "JOIN ORDER_DM ORH ON SAF.ORDER_KEY = ORH.ORDER_KEY JOIN PRODUCT_DM PRD ON SAF.PRODUCT_KEY = PRD.PRODUCT_KEY JOIN DOCUMENT_DM DOC " _
        & "ON SAF.DOCUMENT_KEY = DOC.DOCUMENT_KEY JOIN LU_ITEM ITM ON SAF.ITEM_NUMBER = ITM.ITEM_NUMBER JOIN LU_ADDRESS ADR ON DOC.SHIP_TO_ADDRESS_KEY = ADR.ADDRESS_KEY " _
        & "WHERE ITM.ITEM_CATEGORY_KEY NOT IN ('31010') AND SAF.TRACKING_CODE NOT IN ('F') AND PRD.PRODUCT_LINE_KEY NOT IN ('UN') AND PRD.PRODUCT_SUB_LINE_KEY NOT IN ('60P') " _
        & "AND SAF.TRACKING_NUMBER = " & contractNumber & " AND SAF.EXTENDED_AMOUNT > 0 AND DOC.DOCUMENT_DATE_KEY BETWEEN CONVERT(Date, " & startdate & " , 120) AND CONVERT(Date," & enddate & " , 120) " _
        & "GROUP BY ORH.CUSTOMER_PO_NUMBER, DOC.DOCUMENT_DATE_KEY,SAF.ITEM_NUMBER,SAF.Tracking_Number ORDER BY SAF.Tracking_Number,DOC.DOCUMENT_DATE_KEY")

    ' Check we have data.
    If Not rs.EOF Then
        ' Transfer result.
        Sheets("Detail").Range("A1").CopyFromRecordset rs
    ' Close the recordset
        rs.Close
    Else
        MsgBox "Error: No records returned.", vbCritical
    End If

    ' Clean up
    If CBool(conn.State And adStateOpen) Then conn.Close
    Set conn = Nothing
    Set rs = Nothing

End Sub

【问题讨论】:

  • 我假设您工作表上的单元格也被格式化为“日期”。否则,尝试使用cdate 将单元格的值转换为日期。我对第一个视图的另一个建议是使用debug.print 获取sql语句并检查它是否正确传递给数据库。
  • 这是一个 hack 而不是真正的答案,但我们过去总是将日期格式设置为 yyyymmdd 以避免此类问题。 SQL Server 将正确且没有歧义地解释这些。例如,像这样:(...) BETWEEN '" & Year(startdate) & Format$(Month(startdate), "00") & Format$(Day(startdate), "00") & "' AND (...)(实用函数会简化事情)。注意撇号(我们将日期作为字符串传递给 SQL)。
  • 嗨,ssarabando,工作完美!让我为此挠头,这对我有很大帮助-非常感谢!另外,还要感谢 psychicebola 和 Mike 的回答!

标签: sql-server excel vba date variables


【解决方案1】:

我使用的代码如下和“控制”表中的日期 是标准的英国日期 - DD/MM/YYYY

尽管是英国人,我建议使用您的日期格式...

向 SQL Server 传递日期最安全的方法是使用“yyyy-MM-dd”。这保证了无论您身在何处,它都能正常工作。

select * from [SomeTable]
where Update_Time >= '2015-08-06'

【讨论】:

    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 2021-09-28
    • 2015-11-09
    • 1970-01-01
    相关资源
    最近更新 更多