【问题标题】:Why does my SQL statement not find a match with the WHERE statement below?为什么我的 SQL 语句找不到与下面的 WHERE 语句匹配?
【发布时间】:2019-09-25 20:04:26
【问题描述】:

我正在尝试通过 Excel SQL 语句从我的 MS Access 数据库中提取数据。它不会给我任何错误,但它也不会提取我正在搜索的数据。

如果items(u, 1) 是文本(例如 308-203BL),那么它可以完美运行。

我尝试将它们作为文本和数字进行比较,但当 items(u, 1) 为 19310 时,都找不到任何匹配项。

这会将其作为文本进行比较...

LEFT(Item," & Len(items(u, 1)) & ") = '" & items(u, 1) & "'"

这会将其作为数字进行比较...

VAL(LEFT(Item," & Len(items(u, 1))) & ") = " & items(u, 1)

我已验证数据库中有符合给定条件的记录。

items() 是由items = Range("Items").Value 从工作表上的一列表填充的数组。
以这两个 SKU 为例,第一个有效,第二个无效,数组如下。 .
SKU by SKU,它们被输入到 SQL 中,如下所示。

对于示例中的输入,我收到的输出是一个仅填充第二个项目的销售额的数组。我将 SKU 放入表中的顺序不会改变该结果。我已经用多个 SKU 对其进行了测试,无论我使用多少,它都会返回正确的信息,除了不返回任何数字 SKU 的任何结果。

数据库中Item 的字段是一个短文本,这就是为什么我在尝试将其作为文本匹配时使用'" & items(u, 1) & "'" 将SKU 转换为文本,并使用Val() 将该字段转换为尝试将其匹配为数字时的值。两者都给了我函数中的 0 条记录计数,但没有给我一个数据类型错误。

下面是我的代码中确定 SQL 字符串的部分,还有一些后记,它基本上将它塞进一个 UDF,它从数据库中提取信息并将其放入一个数组中。除了在items(u,1) 是数字时找不到匹配项之外,它工作得很好。

DBString = "SELECT Invoice, Line, Inv_Date, Sales_Order, SOLine, SO_Date, CustID, Item, Part_Description, Ship_Qty, Price, Ext_Sales FROM `" & Year(tabledate) & "-" & Format(tabledate, "mm") & "` WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# AND LEFT(Item," & Len(items(u, 1)) & ") = '" & items(u, 1) & "'"
SalesHolder = PullFromDB(DBString, SGMDB)

我也尝试了下面的代码,强制它作为数字而不是文本进行比较,这也没有给我任何错误,但没有找到匹配项。

DBString = "SELECT Invoice, Line, Inv_Date, Sales_Order, SOLine, SO_Date, CustID, Item, Part_Description, Ship_Qty, Price, Ext_Sales FROM `" & Year(tabledate) & "-" & Format(tabledate, "mm") & "` WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# AND VAL(LEFT(Item," & Len(items(u, 1))) & ") = " & items(u, 1)
SalesHolder = PullFromDB(DBString, SGMDB)

下面是 UDF 本身,它从数据库中提取信息。效果很好。

Function PullFromDB(DBStr As String, DBLoc As String) As Variant
    Dim TheDB As Recordset, DBHolder() As Variant

    Set TheDB = OpenDatabase(DBLoc).OpenRecordset(DBStr)
    If TheDB.RecordCount = 0 Then GoTo theexit

    TheDB.MoveLast
    TheDB.MoveFirst

    ReDim DBHolder(0 To TheDB.RecordCount, 1 To TheDB.Fields.Count) As Variant

    For k = 1 To UBound(DBHolder, 2)
        TheDB.MoveFirst
        For j = 0 To UBound(DBHolder)
            If j = 0 Then
                DBHolder(j, k) = TheDB.Fields(k - 1).Name
            Else
                DBHolder(j, k) = TheDB.Fields(k - 1).Value
                TheDB.MoveNext
            End If
         Next j
    Next k

theexit:
    TheDB.Close
    Set TheDB = Nothing
    PullFromDB = DBHolder

On Error GoTo -1
End Function

预期结果是使用符合条件的信息填充数组 SalesHolder。

我错过了什么?我要瞎找了。

【问题讨论】:

  • items(u, 1) 中包含什么?请展示。您还告诉我们不符合标准但不向我们显示任何数据。实际发生了什么?没有返回结果?
  • 嗨。在数据库中,您的字段是文本还是数字?
  • @Parfait 我已经用你要求的问题更新了我的问题。
  • @LuisCurado 我已经用答案更新了我的帖子。
  • 为什么需要 Left()?表格中的数据与 Excel 中的数据不完全相同?可以尝试相反,确保数字被读取为字符串:CStr(Item)。如果字段是文本类型,确实不需要,但无论如何都要尝试。

标签: sql excel vba ms-access where-clause


【解决方案1】:

感谢大家对此的回复,事实证明我完全是在寻找错误的问题。我发布的代码实际上是正确的,问题在于数据库中Inv_Date 字段的格式。我错误地将过去几个月输入为文本而不是日期,因此我的 SQL 的 WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# 部分不匹配任何内容。

由于 SKU 本身的销售时间,我之前没有发现这是问题所在,这纯属巧合。当我扩大日期范围时,我发现它确实返回了数字 SKU 的结果,但数字和文本 SKU 都在两个月前被切断了。

再次感谢您!

【讨论】:

    猜你喜欢
    • 2017-01-02
    • 2016-11-16
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多