我收到以下错误,无法找出原因:
执行数据库查询时出错。 [Macromedia] [SQLServer JDBC驱动程序] [SQLServer]'附近的语法不正确'。 错误发生在第141行。
<cfquery datasource="mySource" name="getTravel">
select traveler, customernumber, destination, tripdate, purpose, empid, pm_reportid, company
from mySource.dbo.PM_Travel
where pm_reportid in
(
<cfloop from="1" to="#getRecentReports.recordcount#" index="i">
<cfif i lt getRecentReports.recordcount>
#getRecentReports.pm_reportid[i]#,
<cfelse>
#getRecentReports.pm_reportid[i]#
</cfif>
</cfloop>
)
order by customernumber
</cfquery>
第141行是:
where pm_reportid in (<cfloop from="1" to="#getRecentReports.recordcount#" index="i"><cfif i lt getRecentReports.recordcount>#getRecentReports.pm_reportid[i]#, <cfelse>#getRecentReports.pm_reportid[i]#</cfif></cfloop>)
这不是我写的,我是CF的新手。任何帮助表示赞赏。
答案 0 :(得分:7)
试试这个:
where pm_reportid in ( <cfqueryparam value="#valueList(getrecentReports.pm_report_id)#" list="true" cfSqlType="CF_SQL_NUMERIC" /> )
您可能需要更改cfSqlType
的值以匹配“pm_report_id列”中包含的数据类型。如果是文字,请尝试使用CF_SQL_VARCHAR
解释发生了什么:
valueList()
以“queryName.columnName”的语法获取查询列,并将其转换为逗号分隔列表。
cfqueryparam
参数化查询,这将为您提供SQL方面的性能提升,并提供一些安全性,因为数据作为特定数据类型传递。
答案 1 :(得分:4)
(从评论中跟进)
正如我所提到的,cfloop代码可能生成了无效的sql语句。由于查询包含零(0)记录,这将产生一个空子句:
WHERE Col IN ( {nothing here} )
...或其中一个id为null,这将创建一个带有额外逗号的无效子句,如:
WHERE Col (11,22,33,{no value here},44)
Scott's answer显示了一种处理此问题的方法。另一种选择是使用JOIN而不是循环查询结果。只需加入匹配列上的两个表,然后使用相应的WHERE
过滤器。确切的SQL取决于两个表之间的关系,但下面是一般的想法。我不知道所涉及的列的确切名称或数据类型,因此请根据需要进行修改。
<cfquery ....>
SELECT t.traveler, t.customernumber, t.destination, ...more columns ...
FROM PM_Travel t INNER JOIN pm_reports r
ON t.pm_reportid = r.pm_reportid
WHERE r.empID = <cfqueryparam value="#form.empid#" cfsqltype="cf_sql_integer">
AND r.weekID = <cfqueryparam value="#form.weekid#" cfsqltype="cf_sql_integer">
</cfquery>
旁注,我知道这是一个继承的应用程序,但请务必在所有用户提供的值上使用cfqueryparam
。两者都是为了提高性能,并提供额外的保护,以防止常见形式的SQL注入,正如斯科特提到的那样。您可以在CF文档中找到mapping of the cfsqltypes by dbms。