首先让我说,我根本不喜欢这种方法。看起来你正在尝试使用cfquery作为通用包装 - 一种“插入”变量列表的方式。这会让您的查询被其他代码遮蔽。通过查看查询是最容易受到攻击的向量,更不用说通常包含用户输入,这使得查询变得更加困难。此外,CFQUERY是CF语言的强度 - 你可以剪切和从DB IDE和变化的可变投入简单(当然增加的cfqueryparam)粘贴几种语言之一。
最后,您的查询需要cfqueryparam来保护SQLi - 所以在回答您问题的最后部分时 - 是的,这段代码很脆弱。如果不使用cfqueryparam,很少有情况。
所以......这里有一个解决方案(同样,我不喜欢或推荐:),你可以作为一个起点使用:
<cfscript>
var sqlInsertCols = "";
var sqlInsertValues = "";
// some looping and other processing here to fill the lists
...
</cfscript>
<cfquery datasource="..." name="insert">
INSERT INTO MyTable(#sqlInsertACols#)
VALUES (
<cfloop list="#sqlinsertValues#" index="colVal">
<cfif isDate(colVal)>
<Cfqueryparam cfsqltype="CF_SQL_DATE" value="#colval#"/>
<cfelse>
<cfqueryparam cfsqltype="CF_SQL_CHAR" value="#colval#"/>
</cfif>
<cfif colVal IS NOT listlast(sqlInsertValues)>
,
</cfif>
</cfloop>
)
</cfquery>
这假定确定为日期字段被插入类型为“日期”的DB中的列中。它还假定所有“其他”非日期字段都是字符字段。您可能需要为数字或整数或数据中的任何内容添加检查。
此外,如果你需要核对值的列名,你可以使用listgetat如下:
<cfscript>
var sqlInsertCols = "";
var sqlInsertValues = "";
// some looping and other processing here to fill the lists
...
</cfscript>
<cfquery datasource="..." name="insert">
INSERT INTO MyTable(#sqlInsertACols#)
VALUES (
<cfloop from="1" to="#listlen(sqlinsertValues)#" index="x">
<cfif listgetat(sqlInsertCols,x) IS 'dateadded'>
<Cfqueryparam cfsqltype="CF_SQL_DATE" value="#listgetat(sqlInsertValues,x)#"/>
<cfelseif listgetat(sqlInsertCols,x) IS 'userid'>>
<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#listgetat(sqlInsertValues,x)#"/>
</cfif>
<cfif x IS NOT listlen(sqlInsertValues)>
,
</cfif>
</cfloop>
)
</cfquery>
最后,完全不建议快速和肮脏解决方案,你可以试试这个:
<cfscript>
var sqlInsertCols = "";
var sqlInsertValues = "";
// some looping and other processing here to fill the lists
...
</cfscript>
<cfquery datasource="..." name="insert">
INSERT INTO MyTable(#sqlInsertACols#)
VALUES (
<cfloop list="#sqlinsertValues#" index="colVal">
'#colval#'
<cfif colVal IS NOT listlast(sqlInsertValues)>
,
</cfif>
</cfloop>
)
</cfquery>
这可能是因为您的RDBMS隐式转换 - 它可以从字符转换为日期,int或数字在许多/大多数情况下。当然你可能会轻易得到一个语法错误。
最后请注意:上述第一和第三个样品用一些简单的方法来插入列表中的逗号 - 比较值在列表中的最后一个值和插入,如果他们不匹配。所以这个假设未来任何项目没有持续列表是不一样的,在列表中的最后一项。如果最后一项在您的查询中重复出现,那么您将得到一个缺少逗号的语法错误。祝你好运!
ERRATA: 仅供参考 - 在最后一个片段中 - 单引号外变量不会被CFQUERY转义..所以当您使用'#varName#'时 - 单引号将被保留,但是当它们位于变量内时它们会被转义 - 因为CF自然会认为(并且最佳实践是指示)您正在处理要以可变形式插入的内容,而不是查询语言本身。
尝试'sqlInsertValues = ListAppend(sqlInsertValues,CreateODBCDateTime(myDateVar));'。 – xpa1492 2014-11-03 03:36:28
@ xpa1492 - 工作!谢谢!如果您将其作为答案发布,我会接受它 – froadie 2014-11-03 08:34:39
比@ xpa1492的建议效率稍高于首先创建日期变量,而不是随后转换的字符串变量。 – 2014-11-03 13:13:35