【问题标题】:Building Select Statement构建选择语句
【发布时间】:2015-05-21 17:33:33
【问题描述】:

在相应的查询表单上使用单选按钮时,以下 SELECT 语句可以正常工作,但是当我将单选更改为复选框并在选中 2 个或更多复选框的情况下执行查询时会出错。任何关于我做错的建议将不胜感激。

strSelect = "SELECT * FROM qryMyQuery WHERE"
Select Case strOption
Case "Name" 
  strSelect = strSelect & " Name='" & UCase(strName) & "'"

Case "Location" 
  strSelect = strSelect & " Location='" & UCase(strLocation) & "'"

Case "Type"
  strSelect = strSelect & " Type='" & UCase(strType) & "'"

Case "Season"
  strSelect = strSelect & " Season='" & UCase(strSeason) & "'"

Case "Duration"
  strSelect = strSelect & " Duration='" & UCase(strDuration) & "'"

Case "Year"
  strSelect = strSelect & " Year='" & UCase(strYear) & "'"

End Select 

错误发生在 SELECT 语句后不久的第 111 行,就在我建立数据库连接之后。

第 111 行: 设置 RS = dB.Execute(strSelect)

错误如下:

用于 ODBC 驱动程序的 Microsoft OLE DB 提供程序错误“80040e14” [Microsoft][ODBC Microsoft Access Driver] WHERE 子句中的语法错误。 /query2.asp,第 111 行

这是简化的查询表单...

<%@ Language="VBScript" %>

<%

' *** Dim the variables ***
Dim strName
Dim strLocation
Dim strType
Dim strSeason
Dim strYear
Dim strDuration
Dim strSubmit
Dim DB
Dim strInsert
Dim seloption

' *** Open the database ***
Set DB = Server.CreateObject("ADODB.Connection")
DB.ConnectionTimeout=60
DB.Open "XXXX"

%>

<FORM ACTION="query2.asp" METHOD="get">

<B>Object Name:</B>
<INPUT TYPE="checkbox" NAME="seloption" VALUE="Name" CHECKED>
<INPUT TYPE="text" NAME=Name>

<B>Location/Region:</B>
     <INPUT TYPE="checkbox" NAME="seloption" VALUE="Location">
     <SELECT size=1 name=Location>
     <option name="Location" value="AAA">AAA</option>
     <option name="Location" value="BBB">BBB</option>
      </select>

<B>Season:</B>
     <INPUT TYPE="checkbox" NAME="seloption" VALUE="Season">
     <SELECT size=1 name=Season>
     <option name="Season" value="Summer">Summer</option>
      <option name="Season" value="Fall">Fall</option>
      </select>

    <B>Type:</B>
    <INPUT TYPE="checkbox" NAME="seloption" VALUE="Type">
     <SELECT size=1 name=Type>
      <option name="Type" value="CCC">CCC</option>
      <option name="Type" value="DDD">DDD</option>
     </select>  

<B>Year:</B>
  <INPUT TYPE="checkbox" NAME="seloption" VALUE="Yr">
    <SELECT size=1 name=Yr>
    <option name="Year" value="2015">2015</option>
    <option name="Year" value="2014">2014</option>
    <option name="Year" value="various">various</option>
    </select>

<B>Duration:</B>
<INPUT TYPE="checkbox" NAME="seloption" VALUE="Duration">
    <SELECT size=1 name=Duration>
    <option name="Duration" value="1 day">1 day</option>
    <option name="Duration" value="2 days">2 days</option>
    <option name="Duration" value="na">n/a</option>
    </select>

     <INPUT TYPE="submit" VALUE="Submit Query">
     <INPUT TYPE="submit" VALUE="Show All" NAME="btnAll">
     <INPUT TYPE="reset" VALUE="Clear Form">

</FORM>

<%
dB.Close
%>

【问题讨论】:

  • 您的年份是否存储为字符串?即您是否需要将年份标准用引号括起来?
  • 你能打印产生这个错误的查询吗?
  • 表中的列以数值命名(即 2010、2011 等)。话虽如此,我似乎记得在 MS Access 中保留了 Year 一词,不应该使用?
  • 查询表格如下- 篇幅见谅...
  • 抱歉,字符太多,无法在此处粘贴。有关如何发布查询表单的任何建议?

标签: vbscript


【解决方案1】:

至少,您有一些保留字用作需要方括号的字段名称,以便它们被正确解释为存储的 qryMyQuery 查询的字段。

strSelect = "SELECT * FROM qryMyQuery WHERE"
Select Case strOption
    Case "Name" 
      strSelect = strSelect & " [Name]='" & UCase(strName) & "'"
    Case "Location" 
      strSelect = strSelect & " Location='" & UCase(strLocation) & "'"
    Case "Type"
      strSelect = strSelect & " [Type]='" & UCase(strType) & "'"
    Case "Season"
      strSelect = strSelect & " Season='" & UCase(strSeason) & "'"
    Case "Duration"
      strSelect = strSelect & " Duration='" & UCase(strDuration) & "'"
    Case "Year"
      strSelect = strSelect & " [Year]=" & strYear
End Select 

请注意,我将 [YEAR] 字段解释为数字。

【讨论】:

  • 谢谢。我按照建议添加了方括号,并将代码中的列名和引用从 Year 更改为 Yr。不幸的是,同样的错误。
  • 我倾向于坚持使用 T-SQL 的视图和表,但我知道使用 QueryDef object 更好地访问 Access 存储的查询(更多信息请参见 DAO Querydef: Using Querydefs)。您是否使用直接的 SELECT 语句而没有过滤器?可以在将连接的 SELECT 语句发送到 db 引擎之前将其输出以供检查吗?
【解决方案2】:

我怀疑您的变量之一是直接从 html 复选框提供的,对吗?

在这种情况下,如果您选择了许多具有相同名称的复选框,您最终会得到一个类似 strYear = "2014, 2015, 2016" 的值,因为当您读取请求时,具有相同名称的复选框的值会连接在一起,这将无法评估为sql 查询中的整数。

但调试查询的最佳方法是打印 sql 语法,只需将 Set RS = dB.Execute(strSelect) 行替换为 Response.Write strSelect

更新

根据您的 cmets,我想我知道发生了什么,当您执行 strOption = Request.QueryString("seloption") 时,因为许多输入都有此名称,您会得到一个类似 strOption = "Location, Type, Year" 的值,因此您的代码不会输入任何选择的情况,并且您的查询最终只有SELECT * FROM qryMyQuery WHERE,这将解释您收到的错误消息。

如果您允许用户检查许多选项,则无论如何您都必须重构 Select Case,您可以为复选框保留相同的名称,但只需像这样循环请求值:

strSelect = "SELECT * FROM qryMyQuery"
bolFirst = True
For Each strOption In Split(Request.QueryString("seloption"), ", ")

    If bolFirst Then
        strSelect = strSelect & " WHERE"
        bolFirst = False
    Else
        strSelect = strSelect & " AND"
    End If

    Select Case strOption
        Case "Name" 
          strSelect = strSelect & " Name='" & UCase(strName) & "'"

        Case "Location" 
          strSelect = strSelect & " Location='" & UCase(strLocation) & "'"

        Case "Type"
          strSelect = strSelect & " Type='" & UCase(strType) & "'"

        Case "Season"
          strSelect = strSelect & " Season='" & UCase(strSeason) & "'"

        Case "Duration"
          strSelect = strSelect & " Duration='" & UCase(strDuration) & "'"

        Case "Year"
          strSelect = strSelect & " Year='" & UCase(strYear) & "'"

    End Select 
Next

其他需要考虑的事项:

  • 您会发现使用调试器来跟踪您的代码非常有用,您 会更容易发现问题
  • 考虑使用ADO parameters 而不是连接 sql查询字符串中的值以防止sql injection

【讨论】:

  • 这在你的代码片段中是不正确的,它们都有 name="seloption"
  • 啊,是的……好点。我认为你在这里有所作为。我可以将每个 CHECKBOX 更改为使用唯一名称,但这会破坏上面的 SELECT 语句(Select Case strOption),因为我定义了以下 strOption = Request.QueryString("seloption")
  • 我用现在出现的代码和我的观察回应了您的回答。谢谢!
  • Jonathan,经过仔细检查,我似乎在表单的 SELECT 标记中省略了几个双引号。如:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 2013-06-22
相关资源
最近更新 更多