我正在尝试使用CF变量为FIELDS和WHERE子句构建查询。
我使用以下代码收到“执行数据库查询时出错”。当我渲染CF变量以给出文字,然后将查询主体基于结果文字时,一切正常。我已经确认#strFlds#部分可以正常工作,但它似乎在#strWhere#部分窒息。使用WHERE子句的变量是否有问题? (如果重要,数据源是SQL-Server数据库)。
<cfset strWhere = " WHERE SCHYEAR = '#Form.yrVal#'">
<cfset strFlds = "T1, T2">
<cfquery name="qryFld" datasource="TSQL">
SELECT #strFlds# FROM TABLE1 #strWhere#
</cfquery>
答案 0 :(得分:5)
您最有可能遇到阻止SQL注入的CF安全功能。
最好将where语句变量移动到cfqueryparams。
SELECT #strFlds#
FROM Table1
WHERE SCHYear = <cfqueryparam value="#form.yrVal#" cfsqltype="cf_sql_varchar">
答案 1 :(得分:5)
这是因为你构建SQL语句的方式是你在SQL本身中有硬编码的值,即:
WITH s
AS (SELECT *,
COUNT(CASE
WHEN [Flag] <> 'C' THEN 1
END)
OVER(
PARTITION BY [Item] ) AS NonC_Count
FROM Stationery)
SELECT Item,
Date,
Flag
FROM s
WHERE [Flag] <> 'C'
OR NonC_Count = 0;
其中包含SQL:<cfset strWhere = " WHERE SCHYEAR = '#Form.yrVal#'">
和值WHERE SCHYEAR =
。一个人不应该真的这样做,事实上,当你的价值观进一步嵌入表达式中时,ColdFusion会不顾一切地混淆它,以便降低SQL注入的风险(如果你是将来自'#Form.yrVal#'
的值直接传递到数据库中。这是真正的不良做法。
您需要做的是将值作为参数传递给数据库驱动程序。一种方法是将值与SQL语句中最终使用的值分开。 @Chris已经通过内联form
标记向您展示了一种方法。如果您使用<cfqueryparam>
标签,这是唯一的方法。
如果您正在使用ColdFusion 11(总是确保在此处提出问题时指定使用的CF版本,顺便说一句),那么您可以在SQL中使用占位符作为参数:
<cfquery>
如果您使用的是CF9-10,那么使用Query.cfc可以实现同样的功能。
<cfset qryFld = queryExecute("
SELECT #strFlds# FROM TABLE1 WHERE SCHYEAR = ?
", [{value=Form.yrVal, cfsqltype="CF_SQL_VARCHAR"}])>
使用qryFld = new Query(
sql = "SELECT #strFlds# FROM TABLE1 WHERE SCHYEAR = ?",
parameters = [{value=Form.yrVal, cfsqltype="CF_SQL_VARCHAR"}]
).execute().getResult();
以这种方式完全从SQL中去除值是不可能的,这在实现上有点不足。我为此提出了一张票,你可能会投票给我:Separate parameters from SQL in <cfquery>
。
进一步相关阅读(来自我的博客):
答案 2 :(得分:1)
您应该在cfquery
内部创建查询字符串,而不是使用变量构建查询。而且如果你想创建查询字符串动态的各个部分,你总是可以使用条件语句。就像Chris建议总是尝试使用cfqueryparam
来传递值来查询。像这样。
<cfquery name="xyz" datasource="abc">
SELECT
<cfif condition>
col1
</cfif>
<cfif condition>
, col2
</cfif>
FROM TABLE1
WHERE 1=1
<cfif condition>
AND col1 = <cfqueryparam value="#form.formfield1#" cfsqltype="cf_sql_varchar">
</cfif>
<cfif condition>
AND col2 = <cfqueryparam value="#form.formfield12#" cfsqltype="cf_sql_varchar">
</cfif>
</cfquery>