【问题标题】:SQL Query in MS Access VBAMS Access VBA 中的 SQL 查询
【发布时间】:2011-05-08 00:43:39
【问题描述】:

表单数据记录源中的此查询工作正常,返回我想要的确切值

SELECT tblRevRelLog_Detail.RevRelTrackingNumber, tblRevRelLog_Detail.PartNumber, tblRevRelLog_Detail.ChangeLevel, tblRevRelLog_Detail.Version, tblRevRelLog_Detail.JobPnType, tblRevRelLog_Detail.EdsName, tblRevRelLog_Detail.DetailerNamePerPartNumber, tblRevRelLog_Detail.DetailerCompanyPerPartNumber
FROM tblRevRelLog_Detail 
LEFT JOIN tblEventLog ON tblRevRelLog_Detail.PartNumber = tblEventLog.PartNumber
WHERE (((tblEventLog.PartNumber) Not In 
    (SELECT tblEventLog.PartNumber 
     FROM tblEventLog 
     WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper' 
         AND tblEventLog.TrackingNumber =  tblRevRelLog_Detail.RevRelTrackingNumber)))
ORDER BY tblRevRelLog_Detail.PartNumber;

但如果我在 VBA 中编写相同的查询。它没有返回任何东西

strNewSql = "SELECT tblRevRelLog_Detail.PartNumber, tblRevRelLog_Detail.ChangeLevel, tblRevRelLog_Detail.ID FROM tblRevRelLog_Detail LEFT JOIN tblEventLog ON tblRevRelLog_Detail.PartNumber = tblEventLog.PartNumber"
strNewSql = strNewSql & " WHERE ((tblEventLog.PartNumber) Not In (SELECT tblEventLog.PartNumber FROM tblEventLog WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper' AND tblEventLog.TrackingNumber =  tblRevRelLog_Detail.RevRelTrackingNumber);"

查询有问题??谁能帮帮我!

【问题讨论】:

  • 你有没有打印出你查询返回的sql并粘贴到查询设计窗口中?您可以使用Debug.Print strNewSql 执行此操作,这将打印到即时窗口。
  • 这个查询现在显示记录,但它显示了数据库中的所有零件号。当我在表单中使用相同的查询时。它正在显示与跟踪号相关的正确零件号。但是如果我在 VBA 中使用相同的查询。那就是显示数据库中的所有零件号。

标签: sql ms-access vba ms-access-2003


【解决方案1】:

我怀疑你的变量 tempTrackingNumber 不好

【讨论】:

  • 如果我也使用此条件,它不会返回任何内容 tblEventLog.TrackingNumber = tblRevRelLog_Detail.RevRelTrackingNumber
  • 比如 RevRelTrackingNumber 真的是文本字段吗?
  • 在第一个查询中,您的 WHERE 过滤器正在比较列与列(隐式内部联接)(AND tblEventLog.TrackingNumber = tblRevRelLog_Detail.RevRelTrackingNumber),而第二个查询是针对特定单个值的列。检查子查询是否返回了某些内容。
【解决方案2】:

如果RevRelTrackingNumber 是数字,则无需将其括在引号中。

【讨论】:

    【解决方案3】:

    tempTrackingNumber 的数据类型是什么?您的代码(前面截断)显示了这一点:

    ...tblRevRelLog_Detail.RevRelTrackingNumber = """ & tempTrackingNumber & """);"
    

    这意味着它是一个字符串,它将被视为这样。

    如果它实际上是数字,你会想要这个:

    ...tblRevRelLog_Detail.RevRelTrackingNumber = " & tempTrackingNumber & ");"
    

    【讨论】:

    • tempTrackingNumber 是字母数字
    【解决方案4】:

    首先,查询不一样。例如,您的纯文本 SQL 在 SELECT 子句中有八列,而 VBA 版本只有三列。

    其次,您在同一范围内使用了两次相同的表名tblEventLog。因此,您至少需要使用一个表相关名称。我知道 tbl- 前缀是 Access 世界中的一个“骄傲点”,但它确实使您的表名更长且更难阅读 IMO(并且前缀被 ISO 11179 Standard 明确禁止用于数据元素命名:)).. . 那么为什么不自始至终使用表相关名称呢?

    第三,IIRC EXISTS 在 Access (ACE/Jet/whatever) 方面的表现优于 IN,而且 IMO 更容易理解(DISTINCT..INNER JOIN 可能表现更好,但又更难阅读,IMO)。

    这是一个建议的重写:

    SELECT D1.PartNumber, D1.ChangeLevel, 
           D1.ID 
      FROM tblRevRelLog_Detail AS D1
           LEFT OUTER JOIN tblEventLog AS E1
              ON D1.PartNumber = E1.PartNumber 
     WHERE NOT EXISTS (
                       SELECT *
                         FROM tblEventLog AS E2 
                        WHERE E2.EventTypeSelected = 'pn REMOVED From Wrapper' 
                              AND E2.TrackingNumber = D1.RevRelTrackingNumber
                              AND E2.PartNumber = E1.PartNumber
                      ); 
    

    更新:似乎我对 EXIST 给予更好的看法是错误的,所以这里有几个重写可供选择:

    SELECT D1.PartNumber, D1.ChangeLevel, 
           D1.ID 
      FROM tblRevRelLog_Detail AS D1
           LEFT OUTER JOIN tblEventLog AS E1
              ON D1.PartNumber = E1.PartNumber 
     WHERE E1.PartNumber NOT IN 
           (
            SELECT E2.PartNumber
              FROM tblEventLog AS E2 
             WHERE E2.EventTypeSelected = 'pn REMOVED From Wrapper' 
                   AND E2.TrackingNumber = D1.RevRelTrackingNumber
           ); 
    

    实际上,我正在努力使用 Access 的专有联接重新编写此内容。我不断收到“灾难性故障”错误。这是重现代码,我哪里出错了?:

    Sub grjieopgj()
    
      On Error Resume Next
      Kill Environ$("temp") & "\DropMe.mdb"
      On Error GoTo 0
    
      Dim cat
      Set cat = CreateObject("ADOX.Catalog")
      With cat
        .Create _
            "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=" & _
            Environ$("temp") & "\DropMe.mdb"
        With .ActiveConnection
    
          Dim Sql As String
          Sql = _
          "CREATE TABLE tblRevRelLog_Detail " & vbCr & "(" & vbCr & _
          " PartNumber VARCHAR(20), " & vbCr & " EventTypeSelected VARCHAR(20), " & vbCr & _
          " TrackingNumber VARCHAR(20), " & vbCr & " RevRelTrackingNumber VARCHAR(20), " & vbCr & _
          " ChangeLevel VARCHAR(20), ID VARCHAR(20)" & vbCr & ");"
          .Execute Sql
    
          Sql = _
          "CREATE TABLE tblEventLog " & vbCr & "(" & vbCr & _
          " PartNumber VARCHAR(20), " & vbCr & " EventTypeSelected VARCHAR(20), " & vbCr & _
          " TrackingNumber VARCHAR(20), " & vbCr & " RevRelTrackingNumber VARCHAR(20), " & vbCr & _
          " ChangeLevel VARCHAR(20), ID VARCHAR(20)" & vbCr & ");"
    
          Sql = _
          "SELECT DISTINCT D1.PartNumber, D1.ChangeLevel," & _
          " " & vbCr & "       D1.ID " & vbCr & "  FROM (" & vbCr & "        tblRevRelLog_Detail" & _
          " AS D1" & vbCr & "        LEFT OUTER JOIN tblEventLog" & _
          " AS E1" & vbCr & "          ON D1.PartNumber = E1.PartNumber" & vbCr & "" & _
          "       )" & vbCr & "       LEFT OUTER JOIN tblEventLog" & _
          " AS E2" & vbCr & "          ON AND E2.TrackingNumber" & _
          " <> D1.RevRelTrackingNumber" & vbCr & "           " & _
          "  AND E2.PartNumber <> E1.PartNumber" & vbCr & " WHERE" & _
          " E2.EventTypeSelected = 'pn REMOVED From" & _
          " Wrapper';"
    
          Dim rs
          Set rs = .Execute(Sql)
          MsgBox rs.GetString
        End With
        Set .ActiveConnection = Nothing
      End With
    End Sub
    

    【讨论】:

    • NOT EXISTS 在双方的索引使用方面并不比 NO IN 更可靠。事实上,根据我的经验,情况并非如此。
    • @David-W-Fenton:我现在使用NOT IN 重新编写,但我的JOIN 重新编写出现“灾难性故障”错误(请参阅 VBA 的回答)。知道这意味着什么吗?
    • 我从未在 Jet/ACE/Access 错误消息中看到那些令人震惊的词。 NOT IN 在两边都使用索引也不可靠。但是,EXISTS 和 IN 都使用两边的索引。也许有一些方法可以在另一个层面扭转逻辑?
    【解决方案5】:

    好像你缺少一个右括号。在 VBA 中的查询末尾添加“)”并尝试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多