【问题标题】:How to troubleshoot SQL query within VBA code?如何对 VBA 代码中的 SQL 查询进行故障排除?
【发布时间】:2018-11-20 14:20:07
【问题描述】:

我创建了一个 SQL 语句来计算我收集的所选字段的总和。我有在 MS Access 中工作的查询,但是当我在我的数据库中将其转换为 VBA 编码时,它会吐出一个编译错误:语法错误。下面我附上了我的工作查询以及我的语法查询。

MS Access 中的查询如下所示:

SELECT 1,'Passed - Depot' AS QRY, Sum(IIf(([PreStressStackDate]>=[StartDate] And [PreStressStackDate]<=[EndDate]) And (([CurrentLevelOfCompletion]>=5 And [CurrentLevelOfCompletion]<1073741829) Or [CurrentLevelOfCompletion]>1073741829),1,0)) AS [PreStress Stackup], Sum(IIf(([StackCompressionDate]>=[StartDate] And [StackCompressionDate]<=[EndDate]) And (([CurrentLevelOfCompletion]>=21 And [CurrentLevelOfCompletion]<1073741845) Or [CurrentLevelOfCompletion]>1073741845),1,0)) AS [Stack Compression], Sum(IIf(([TestingDate]>=[StartDate] And [TestingDate]<=[EndDate]) And (([CurrentLevelOfCompletion]>85 And [CurrentLevelOfCompletion]<1073741909) Or [CurrentLevelOfCompletion]>1073741909),1,0)) AS Testing, Sum(IIf(([ShroudAssemblyDate]>=[StartDate] And [ShroudAssemblyDate]<=[EndDate]) And (([CurrentLevelOfCompletion]>=341 And [CurrentLevelOfCompletion]<1073742165) Or [CurrentLevelOfCompletion]>1073742165),1,0)) AS [Shroud Assembly], Sum(IIf(([TransformerInstallDate]>=[StartDate] And [TransformerInstallDate]<=[EndDate]) And (([CurrentLevelOfCompletion]>=1365 And [CurrentLevelOfCompletion]<1073743189)),1,0)) AS [Transformer Installation]
FROM TR343DrySide
WHERE (([TransducerSN] Not Like "CR*"));

UNION SELECT 2, 'Failed - Depot' AS QRY, Sum(IIf(([PreStressStackDate]>=[StartDate] And [PreStressStackDate]<=[EndDate]) And [CurrentLevelOfCompletion]=1073741829,1,0)) AS [PreStress Stackup], Sum(IIf(([StackCompressionDate]>=[StartDate] And [StackCompressionDate]<=[EndDate]) And [CurrentLevelOfCompletion]=1073741845,1,0)) AS [Stack Compression], Sum(IIf(([TestingDate]>=[StartDate] And [TestingDate]<=[EndDate]) And [CurrentLevelOfCompletion]=1073741909,1,0)) AS [Testing], Sum(IIf(([ShroudAssemblyDate]>=[StartDate] And [ShroudAssemblyDate]<=[EndDate]) And [CurrentLevelOfCompletion]=1073742165,1,0)) AS [Shroud Assembly], Sum(IIf(([TransformerInstallDate]>=[StartDate] And [TransformerInstallDate]<=[EndDate]) And [CurrentLevelOfCompletion]=1073743189,1,0)) AS [Transformer Installation]
FROM TR343DrySide
WHERE (([TransducerSN] Not Like "CR*"));

运行此查询时,它会计算所选日期之间的字段总和。

下面我附上了我的 VBA 代码,它出现了语法编译错误:

Private Sub cmdDrySideRunReport_Click()

    Dim strDrySQL_New, strDrySQL_Depot       As String
    Dim DryStartDate                         As Date
    Dim DryEndDate                           As Date


  '------------------------------------------------------------------------------------------------------
  If IsNull(Me.txtDryStartDate) Or Me.txtDryStartDate = "" Or IsNull(Me.txtDryEndDate) Or Me.txtDryEndDate = "" Then
        If IsNull(Me.txtDryStartDate) Or Me.txtDryStartDate = "" Then
            MsgBox "Please enter the Start Date"
            Me.txtDryStartDate.SetFocus
        End If
        If IsNull(Me.txtDryEndDate) Or Me.txtDryEndDate = "" Then
            MsgBox "Please enter the End Date"
            Me.txtDryEndDate.SetFocus
        End If
    Else
        DryStartDate = Me.txtDryStartDate
        DryEndDate = Me.txtDryEndDate + 1



        '###########################################################3
        'DRYSIDE NEW


        strDrySQL_New = "Select 1, 'Passed - New' AS QRY, Sum(IIf(([PreStressStackDate]>=#" & DryStartDate & "# And [PreStressStackDate]<=#" & DryEndDate & "#)" & _
                        " And (([CurrentLevelOfCompletion]>=5 And [CurrentLevelOfCompletion]<1073741829) Or [CurrentLevelOfCompletion]>1073741829),1,0)) AS [PreStress Stackup]," & _
                        " Sum(IIf(([StackCompressionDate]>=#" & DryStartDate & "# And [StackCompressionDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=21" & _
                        " And [CurrentLevelOfCompletion]<1073741845) Or [CurrentLevelOfCompletion]>1073741845),1,0)) AS [Stack Compression]," & _
                        " Sum(IIf(([TestingDate]>=#" & DryStartDate & "# And [TestingDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=85" & _
                        vbCrLf & " And [CurrentLevelOfCompletion]<1073741909) Or [CurrentLevelOfCompletion]>1073741909),1,0)) AS [Testing]," & _
                        " Sum(IIf(([ShroudAssemblyDate]>=#" & DryStartDate & "# And [ShroudAssemblyDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=341" & _
                        " And [CurrentLevelOfCompletion]<1073742165) Or [CurrentLevelOfCompletion]>1073742165),1,0)) AS [Shroud Assembly]," & _
                        " Sum(IIf(([TransformerInstallDate]>=#" & DryStartDate & "# And [TransformerInstallDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=1365 And [CurrentLevelOfCompletion]<1073743189)),1,0)) AS [Transformer Installation]" & _
                        " FROM TR343DrySide" & _
                        " WHERE (([TransducerSN] Like ""CR*"")) " & _
                        vbCrLf & " UNION SELECT 2, 'Failed - New' AS QRY, Sum(IIf(([PreStressStackDate]>=#" & StartDate & "#" & _
                        " And [PreStressStackDate]<=#" & EndDate & "#) And [CurrentLevelOfCompletion]=1073741829,1,0)) AS [PreStress Stackup]," & _
                        " Sum(IIf(([StackCompressionDate]>=#" & StartDate & "# And [StackCompressionDate]<=#" & EndDate & "#) And [CurrentLevelOfCompletion]=1073741845,1,0)) AS [Stack Compression]," & _
                        " Sum(IIf(([TestingDate]>=#" & StartDate & "# And [TestingDate]<=#" & EndDate & "#) &" _
                        " And [CurrentLevelOfCompletion]=1073741909,1,0)) AS [Testing], Sum(IIf(([ShroudAssemblyDate]>=#" & StartDate & "# And [ShroudAssemblyDate]<=#" & EndDate & "#)" & _
                        " And [CurrentLevelOfCompletion]=1073742165,1,0)) AS [Shroud Assembly], Sum(IIf(([TransformerInstallDate]>=#" & StartDate & "# And [TransformerInstallDate]<=#" & EndDate & "#)" & _
                        " And [CurrentLevelOfCompletion]=1073742165,1,0)) AS [Transformer Installation]" & _
                        " FROM TR343DrySide" & _
                        " WHERE (([TransducerSN] Like ""CR*""));"







        Me.sfrmCraneDrySidePassFailDateRange_New.Form.RecordSource = strDrySQL_New
        Me.sfrmCraneDrySidePassFailDateRange_New.Visible = True

        '###########################################################
        'DRYSIDE DEPOT
        strDrySQL_Depot = "Select 1, 'Passed - New' AS QRY, Sum(IIf(([PreStressStackDate]>=#" & DryStartDate & "# And [PreStressStackDate]<=#" & DryEndDate & "#)" & _
                        " And (([CurrentLevelOfCompletion]>=5 And [CurrentLevelOfCompletion]<1073741829) Or [CurrentLevelOfCompletion]>1073741829),1,0)) AS [PreStress Stackup]," & _
                        " Sum(IIf(([StackCompressionDate]>=#" & DryStartDate & "# And [StackCompressionDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=21" & _
                        " And [CurrentLevelOfCompletion]<1073741845) Or [CurrentLevelOfCompletion]>1073741845),1,0)) AS [Stack Compression]," & _
                        " Sum(IIf(([TestingDate]>=#" & DryStartDate & "# And [TestingDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=85" & _
                        vbCrLf & " And [CurrentLevelOfCompletion]<1073741909) Or [CurrentLevelOfCompletion]>1073741909),1,0)) AS [Testing]," & _
                        " Sum(IIf(([ShroudAssemblyDate]>=#" & DryStartDate & "# And [ShroudAssemblyDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=341" & _
                        " And [CurrentLevelOfCompletion]<1073742165) Or [CurrentLevelOfCompletion]>1073742165),1,0)) AS [Shroud Assembly]," & _
                        " Sum(IIf(([TransformerInstallDate]>=#" & DryStartDate & "# And [TransformerInstallDate]<=#" & DryEndDate & "#) And (([CurrentLevelOfCompletion]>=1365 And [CurrentLevelOfCompletion]<1073743189)),1,0)) AS [Transformer Installation]" & _
                        " FROM TR343DrySide" & _
                        " WHERE (([TransducerSN] Not Like ""CR*""));"

        Me.sfrmCraneDrySidePassFailDateRange_Depot.Form.RecordSource = strDrySQL_Depot
        Me.sfrmCraneDrySidePassFailDateRange_Depot.Visible = True
    End If
End Sub

我认为错误发生在此语句中:

  "Sum(IIf(([TestingDate]>=#" & StartDate & "# And [TestingDate]<=#" & EndDate & "#) &" _
                        " And [CurrentLevelOfCompletion]=1073741909,1,0)) AS [Testing], Sum(IIf(([ShroudAssemblyDate]>=#" & StartDate & "# And [ShroudAssemblyDate]<=#" & EndDate & "#)" & _
                        " And [CurrentLevelOfCompletion]=1073742165,1,0)) AS [Shroud Assembly],"

【问题讨论】:

  • 错误是什么?
  • 我的工会声明中出现错误 3319。我的想法是我错过了某种标点符号,但无法确定在哪里......
  • 您的错误行是" And [CurrentLevelOfCompletion]=1073741909,1,0)) AS [Testing]" 有结束"[Shroud Assembly]" 和结束" 围绕这个Sum(IIf(([TestingDate]&gt;=#" &amp; StartDate &amp; "# And [TestingDate]&lt;=#" &amp; EndDate &amp; "#)"
  • Sql注入警告xkcd.com/327使用参数化查询
  • 如果你显示Debug.Print strSQL也会更容易,这样我们就可以看到最终的查询

标签: sql vba ms-access


【解决方案1】:

您的字符串不好,并且在这些行中使用流氓" 在您的字符串中变得无效:

" And [CurrentLevelOfCompletion]=1073741909,1,0)) AS [Testing]", Sum(IIf(([ShroudAssemblyDate]>=#" & StartDate & "# And [ShroudAssemblyDate]<=#" & EndDate & "#)" & _

" And [CurrentLevelOfCompletion]=1073742165,1,0)) AS [Shroud Assembly]", Sum(IIf(([TransformerInstallDate]>=#" & StartDate & "# And [TransformerInstallDate]<=#" & EndDate & "#)" & _

这样的多行字符串赋值应该用于使代码更具可读性。在您的情况下,我认为它使事情变得不那么可读并且更难排除故障。我建议从这个 sql 中构建一个查询对象,而不是在 VBA 中构建字符串。仅出于故障排除目的,如果您必须在 vba 中构建它 - 使用更结构化、自连接的方式构建字符串。这种方式更容易看到编译错误。

strDrySQL_New = "SELECT 1 " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,'Passed - New' AS QRY " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [PreStressStackDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [PreStressStackDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   [CurrentLevelOfCompletion] >= 5 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   AND [CurrentLevelOfCompletion] < 1073741829 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "               OR [CurrentLevelOfCompletion] > 1073741829 " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ), 1, 0)) AS [PreStress Stackup] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [StackCompressionDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [StackCompressionDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   [CurrentLevelOfCompletion] >= 21 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   AND [CurrentLevelOfCompletion] < 1073741845 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "               OR [CurrentLevelOfCompletion] > 1073741845 " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ), 1, 0)) AS [Stack Compression] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [TestingDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [TestingDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   [CurrentLevelOfCompletion] >= 85 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   AND [CurrentLevelOfCompletion] < 1073741909 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "               OR [CurrentLevelOfCompletion] > 1073741909 " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ), 1, 0)) AS [Testing] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [ShroudAssemblyDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [ShroudAssemblyDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   [CurrentLevelOfCompletion] >= 341 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   AND [CurrentLevelOfCompletion] < 1073742165 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "               OR [CurrentLevelOfCompletion] > 1073742165 " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ), 1, 0)) AS [Shroud Assembly] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [TransformerInstallDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [TransformerInstallDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ( " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   [CurrentLevelOfCompletion] >= 1365 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   AND [CurrentLevelOfCompletion] < 1073743189 " & vbCrLf
strDrySQL_New = strDrySQL_New & "                   ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ), 1, 0)) AS [Transformer Installation] " & vbCrLf
strDrySQL_New = strDrySQL_New & "FROM TR343DrySide " & vbCrLf
strDrySQL_New = strDrySQL_New & "WHERE (([TransducerSN] LIKE ""CR*"")) " & vbCrLf
strDrySQL_New = strDrySQL_New & " " & vbCrLf
strDrySQL_New = strDrySQL_New & "UNION " & vbCrLf
strDrySQL_New = strDrySQL_New & " " & vbCrLf
strDrySQL_New = strDrySQL_New & "SELECT 2 " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,'Failed - New' AS QRY " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [PreStressStackDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [PreStressStackDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND [CurrentLevelOfCompletion] = 1073741829, 1, 0)) AS [PreStress Stackup] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [StackCompressionDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [StackCompressionDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND [CurrentLevelOfCompletion] = 1073741845, 1, 0)) AS [Stack Compression] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [TestingDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [TestingDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND [CurrentLevelOfCompletion] = 1073741909, 1, 0)) AS [Testing] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [ShroudAssemblyDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [ShroudAssemblyDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND [CurrentLevelOfCompletion] = 1073742165, 1, 0)) AS [Shroud Assembly] " & vbCrLf
strDrySQL_New = strDrySQL_New & "   ,Sum(IIf(( " & vbCrLf
strDrySQL_New = strDrySQL_New & "               [TransformerInstallDate] >= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               AND [TransformerInstallDate] <= ## " & vbCrLf
strDrySQL_New = strDrySQL_New & "               ) " & vbCrLf
strDrySQL_New = strDrySQL_New & "           AND [CurrentLevelOfCompletion] = 1073742165, 1, 0)) AS [Transformer Installation] " & vbCrLf
strDrySQL_New = strDrySQL_New & "FROM TR343DrySide " & vbCrLf
strDrySQL_New = strDrySQL_New & "WHERE (([TransducerSN] LIKE ""CR*"")); " & vbCrLf

上面的代码实际上将debug.print 一个格式很好的SQL 语句;更容易排除故障

【讨论】:

  • 非常感谢您的建议。不幸的是,数据库是用 VBA 构建的,程序中的某些功能必须在 VBA 中。我将研究自我连接我的陈述。第一次真正在 VBA 中编码,对某些主题有点迷茫,非常感谢。
  • 请注意,将多行语句交换为连接可能会对性能产生严重影响。不是分配内存并将字符串复制到内存一次,而是分配内存,复制字符串,分配更大的新内存部分,复制字符串,附加字符串的新部分,释放旧字符串,乘以 20 . 我是在提倡一种不好的做法,这正是其他语言有字符串构建器的原因,因为性能影响不容忽视。
  • @ErikvonAsmuth 是绝对正确的。在您的最终代码中,这不是您应该做的。但是,这将帮助您在字符串中找到语法错​​误的位置。有一种方法可以一次构建字符串要好得多,或者更好 - 从文本文件导入,或者如我所说,使用 queryDef 对象
  • @ErikvonAsmuth 谢谢。我更新了我的问题,让您更详细地了解正在发生的事情。
  • @miroxlav 绝对正确。这是 OP 最初所做的,但在字符串中找不到语法错误。此建议仅用于排除错误在字符串中发生的位置(因为编译器会抱怨字符串的特定行,而不是整个字符串)
猜你喜欢
  • 1970-01-01
  • 2012-03-16
  • 2015-12-23
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
相关资源
最近更新 更多