在变量中使用语句时,Coldfusion 更新查询会抛出错误
Coldfusion update query throws error when using statements in a variable
正在尝试使用包含一组逗号分隔的列更新的变量。该变量最终包含有效的 SQL(或更准确地说是有效的 Coldfusion 语法),但查询会引发错误:[Macromedia][SQLServer JDBC Driver][SQL服务器]“<”附近的语法不正确。
我从要更新的初始专栏开始:
<cfset sqlString = myColumn & ' = <cfqueryparam value="#myValue#" cfsqltype="#myDataType#" null="#NOT len(trim(myValue))#">'>
然后循环遍历一些表单元素:
<cfset sqlString = sqlString & ', ' & myColumn & ' = <cfqueryparam value="#myValue#" cfsqltype="#myDataType#" null="#NOT len(trim(myValue))#">'>
当然,我最终在 sqlString 中得到了一个完整的字符串,但为了便于阅读,它包含如下内容:
id = <cfqueryparam value="123" cfsqltype="cf_sql_integer">,
csp = <cfqueryparam value="5" cfsqltype="cf_sql_integer">,
Q185 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q3 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q177 = <cfqueryparam value="" cfsqltype="cf_sql_date" null="YES">
所以我尝试在这样的更新查询中使用它:
<cfquery name="update_answers" datasource="#application.datasource#">
UPDATE answers
SET #PreserveSingleQuotes(sqlString)#
WHERE rec_id = #id#
</cfquery>
无论是否使用 PreserveSingleQuotes 函数,我都试过了,但均无济于事。
如果我像这样输出 sqlString 的内容并将其直接粘贴到查询中,它工作正常:
<cfquery name="update_answers" datasource="#application.datasource#">
UPDATE answers
id = <cfqueryparam value="123" cfsqltype="cf_sql_integer">,
csp = <cfqueryparam value="5" cfsqltype="cf_sql_integer">,
Q185 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q3 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q177 = <cfqueryparam value="" cfsqltype="cf_sql_date" null="YES">
WHERE rec_id = #id#
</cfquery>
同样,为了便于阅读,我在这里显示了换行符,但是我将 sqlString 内容粘贴到有或没有换行符的查询中都没有关系;它会起作用。
有什么想法吗?
tldr;
CFQueryparam
不能嵌套在字符串中。它必须直接在 <cfquery>
标签中使用。要使用动态参数构建 sql 语句,请查看 cfscript equivalent of cfqueryparam.
安全问题
虽然您可能只是出于绝望才尝试 PreserveSingleQuotes()
,但 永远不会 使用该功能,除非您了解其影响,因为它基本上会造成很大的影响 sql 在您的应用程序中注入孔。
<cfset sqlString = sqlString & ', ' & myColumn
此外,要非常小心这种动态 sql 语句。即使您使用 cfqueryparam 保护所有 参数 ,查询仍然容易受到 sql 注入攻击,因为 myColumn
是用户提供的值。不幸的是,cfqueryparam 不能保护对象名称(table 名称、列名称等),只能保护文字(字符串、日期等)。因此,如果您绝对 必须 在原始 sql 中使用动态列名,请务必根据白名单验证它们,如果检测到无效列,则拒绝请求。
您可以使用以下方法。几年前我写了这个例程,当时我需要动态地建立一个 cfquerparams 数组。
我还添加了 'ReadQuery' 功能,以防万一,您将来需要使用它。
已在 Lucee 4.5 (Windows 2008R2) 和 ACF11 (Windows 10) 上进行了全面测试。
如果您需要有关调用 sysntax 的进一步说明,请告诉我,但我在底部添加了一个示例,以帮助您入门。
这些函数实际上是 CFC 服务的一部分,但您可以独立使用它们:
<!--- FUNCTION UDF: build SQL params --->
<!---
Notes:
Use for building sql with simple read queries:
Supported:
- INNER JOINS
- value paramaterization
- IN operator with or without paramaterization
- ignore WHERE clause item, if a certain value or a value in a list of values, is matched: {...'ignore'='value'}
- ignore value list custom delimeter: default {...'ignoredelimiter'=','}
- use {...'sqltype'='number|string'} for non value paramaterization
- positional paramaters 'table column ?'
Unsupported:
- subqueries
- named parameters, 'table column = :table column', due to a bug with the way Railo parses table prefixed columns sql
--->
<cffunction name="BuildSQLParams" access="public" returntype="string" hint="function description: build SQL params">
<cfargument name="query" required="false" default="#StructNew()#" type="struct" hint="argument description: query">
<cfargument name="params" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: params">
<cfset var result = "">
<cfset var local = StructNew()>
<cfset local.keylist = "column,operator,sqltype,value">
<cfset local.sqlarray = ArrayNew(1)>
<cfif IsStruct(arguments.query) AND ArrayLen(arguments.params)>
<cfloop from="1" to="#ArrayLen(arguments.params)#" index="local.i">
<cfset local.param = arguments.params[local.i]>
<cfif IsStruct(local.param) AND NOT StructIsEmpty(local.param)>
<cfset local.isValidParam = false>
<cfset local.counter = 0>
<cfloop collection="#local.param#" item="local.key">
<cfif ListFindNoCase(local.keylist,local.key)>
<cfset local.counter = local.counter + 1>
</cfif>
</cfloop>
<cfif local.counter EQ ListLen(local.keylist)>
<cfset local.isValidParam = true>
</cfif>
<cfif local.isValidParam>
<cfset local.ignore = false>
<cfset local.ignoredelimiter = ",">
<cfif StructKeyExists(param,'ignoredelimiter')>
<cfset local.ignoredelimiter = param['ignoredelimiter']>
</cfif>
<cfif StructKeyExists(param,'ignore')>
<cfif ListLen(param['ignore'],local.ignoredelimiter)>
<cfif ListFindNoCase(param['ignore'],param['value'],local.ignoredelimiter)>
<cfset local.ignore = true>
</cfif>
<cfelse>
<cfif param['ignore'] EQ param['value']>
<cfset local.ignore = true>
</cfif>
</cfif>
</cfif>
<cfif NOT local.ignore>
<cfif NOT ListFindNoCase("number,string",param['sqltype'])>
<cfif param['operator'] EQ "IN">
<cfset arguments.query.addParam(value=param['value'],cfsqltype="cf_sql_#param['sqltype']#",list="yes")>
<cfelse>
<cfset arguments.query.addParam(value=param['value'],cfsqltype="cf_sql_#param['sqltype']#")>
</cfif>
</cfif>
</cfif>
<cfif NOT local.ignore>
<cfsavecontent variable="local.sql">
<cfoutput>
#param['column']#
#param['operator']#
<cfif ListFindNoCase("number,string",param['sqltype'])>
<cfif param['sqltype'] EQ "number">
#param['value']#
<cfelse>
'#param['value']#'
</cfif>
<cfelse>
<cfif param['operator'] EQ "IN">
(?)
<cfelse>
?
</cfif>
</cfif>
<cfif StructKeyExists(param,'andOr')>
#param['andOr']#
</cfif>
</cfoutput>
</cfsavecontent>
<cfset result = result & local.sql>
</cfif>
</cfif>
</cfif>
</cfloop>
</cfif>
<cfif Len(Trim(result))>
<cfset result = REReplaceNoCase(result,"[\s]+"," ","ALL")>
<cfset result = REReplaceNoCase(result,"[\s]+(AND|OR|,)[\s]*$","","ALL")>
<cfset result = Trim(result)>
</cfif>
<cfreturn result />
</cffunction>
<!--- FUNCTION UDF: read query --->
<!---
Notes:
Use for executing sql with simple read queries:
Supported:
- query attributes: datasource
Unsupported:
- apart from 'datasource', no other query attributes are supported
--->
<cffunction name="ReadQuery" returntype="struct" output="false" access="public" hint="function description: read query">
<!--- arguments --->
<cfargument name="dsn" required="yes" hint="argument description: dsn">
<cfargument name="columns" type="string" required="no" default="" hint="argument description: columns">
<cfargument name="tables" type="string" required="no" default="" hint="argument description: tables">
<cfargument name="params" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: params">
<cfargument name="groupby" type="string" required="no" default="" hint="argument description: group by">
<cfargument name="orderby" type="string" required="no" default="" hint="argument description: order by">
<cfargument name="sortorder" type="string" required="no" default="ASC" hint="argument description: sort order">
<!--- local variables --->
<cfset var result = StructNew()>
<cfset var local = StructNew()>
<!--- logic --->
<cfset StructInsert(result,"query",QueryNew(''))>
<cfset StructInsert(result,"metaInfo",StructNew())>
<cfif Len(Trim(arguments.tables))>
<cfset local.wheresql = "">
<cfset local.groupby = "">
<cfset local.orderby = "">
<cfif Len(Trim(arguments.groupby))>
<cfset local.groupby = " GROUP BY " & arguments.groupby>
</cfif>
<cfif Len(Trim(arguments.orderby))>
<cfset local.orderby = " ORDER BY " & arguments.orderby & " " & arguments.sortorder>
</cfif>
<cfset local.query = new Query()>
<cfset local.query.setAttributes(datasource=arguments.dsn)>
<cfset local.query.setAttributes(name="result")>
<cfif ArrayLen(arguments.params)>
<cfset local.wheresql = BuildSQLParams(local.query,arguments.params)>
</cfif>
<cfif Len(Trim(local.wheresql))>
<cfset local.wheresql = " WHERE " & local.wheresql>
</cfif>
<cfset local.execute = local.query.execute(sql="SELECT #arguments.columns# FROM #arguments.tables##local.wheresql##local.groupby##local.orderby#")>
<cfset result.query = local.execute.getResult()>
<cfset result.metaInfo = local.execute.getPrefix()>
</cfif>
<cfreturn result>
</cffunction>
<!--- FUNCTION UDF: update query --->
<!---
Notes:
Use for executing sql with simple update queries:
Supported:
- query attributes: datasource
Unsupported:
- apart from 'datasource', no other query attributes are supported
--->
<cffunction name="UpdateQuery" returntype="struct" output="false" access="public" hint="function description: read query">
<!--- arguments --->
<cfargument name="dsn" required="yes" hint="argument description: dsn" />
<cfargument name="tables" type="string" required="no" default="" hint="argument description: tables">
<cfargument name="setparams" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: set params">
<cfargument name="whereparams" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: where params">
<!--- local variables --->
<cfset var result = StructNew()>
<cfset var local = StructNew()>
<!--- logic --->
<cfset StructInsert(result,"query",QueryNew(''))>
<cfset StructInsert(result,"metaInfo",StructNew())>
<cfif Len(Trim(arguments.tables))>
<cfset local.setsql = "">
<cfset local.wheresql = "">
<cfset local.query = new Query()>
<cfset local.query.setAttributes(datasource=arguments.dsn)>
<cfset local.query.setAttributes(name="result")>
<cfif ArrayLen(arguments.setparams)>
<cfset local.setsql = BuildSQLParams(local.query,arguments.setparams)>
</cfif>
<cfif Len(Trim(local.setsql))>
<cfset local.setsql = " SET " & local.setsql>
</cfif>
<cfif ArrayLen(arguments.whereparams)>
<cfset local.wheresql = BuildSQLParams(local.query,arguments.whereparams)>
</cfif>
<cfif Len(Trim(local.wheresql))>
<cfset local.wheresql = " WHERE " & local.wheresql>
</cfif>
<cfset local.execute = local.query.execute(sql="UPDATE #arguments.tables##local.setsql##local.wheresql#")>
<cfset result.query = local.execute.getResult()>
<cfset result.metaInfo = local.execute.getPrefix()>
</cfif>
<cfreturn result>
</cffunction>
<cfset sqlarray = ArrayNew(1)>
<cfset wherearray = ArrayNew(1)>
<cfset ArrayAppend(sqlarray,{'column'='id','operator'='=','sqltype'='integer','value'='123','andOr'=','})>
<cfset ArrayAppend(sqlarray,{'column'='csp','operator'='=','sqltype'='integer','value'='5','andOr'=','})>
...
<cfset ArrayAppend(wherearray,{'column'='rec_id','operator'='=','sqltype'='integer','value'=id,'andOr'=''}>
<cfset UpdateQuery(dsn=application.datasource,tables="answers",setparams=sqlarray,whereparams=wherearray)>
正在尝试使用包含一组逗号分隔的列更新的变量。该变量最终包含有效的 SQL(或更准确地说是有效的 Coldfusion 语法),但查询会引发错误:[Macromedia][SQLServer JDBC Driver][SQL服务器]“<”附近的语法不正确。
我从要更新的初始专栏开始:
<cfset sqlString = myColumn & ' = <cfqueryparam value="#myValue#" cfsqltype="#myDataType#" null="#NOT len(trim(myValue))#">'>
然后循环遍历一些表单元素:
<cfset sqlString = sqlString & ', ' & myColumn & ' = <cfqueryparam value="#myValue#" cfsqltype="#myDataType#" null="#NOT len(trim(myValue))#">'>
当然,我最终在 sqlString 中得到了一个完整的字符串,但为了便于阅读,它包含如下内容:
id = <cfqueryparam value="123" cfsqltype="cf_sql_integer">,
csp = <cfqueryparam value="5" cfsqltype="cf_sql_integer">,
Q185 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q3 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q177 = <cfqueryparam value="" cfsqltype="cf_sql_date" null="YES">
所以我尝试在这样的更新查询中使用它:
<cfquery name="update_answers" datasource="#application.datasource#">
UPDATE answers
SET #PreserveSingleQuotes(sqlString)#
WHERE rec_id = #id#
</cfquery>
无论是否使用 PreserveSingleQuotes 函数,我都试过了,但均无济于事。
如果我像这样输出 sqlString 的内容并将其直接粘贴到查询中,它工作正常:
<cfquery name="update_answers" datasource="#application.datasource#">
UPDATE answers
id = <cfqueryparam value="123" cfsqltype="cf_sql_integer">,
csp = <cfqueryparam value="5" cfsqltype="cf_sql_integer">,
Q185 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q3 = <cfqueryparam value="" cfsqltype="cf_sql_integer" null="YES">,
Q177 = <cfqueryparam value="" cfsqltype="cf_sql_date" null="YES">
WHERE rec_id = #id#
</cfquery>
同样,为了便于阅读,我在这里显示了换行符,但是我将 sqlString 内容粘贴到有或没有换行符的查询中都没有关系;它会起作用。
有什么想法吗?
tldr;
CFQueryparam
不能嵌套在字符串中。它必须直接在 <cfquery>
标签中使用。要使用动态参数构建 sql 语句,请查看 cfscript equivalent of cfqueryparam.
安全问题
虽然您可能只是出于绝望才尝试 PreserveSingleQuotes()
,但 永远不会 使用该功能,除非您了解其影响,因为它基本上会造成很大的影响 sql 在您的应用程序中注入孔。
<cfset sqlString = sqlString & ', ' & myColumn
此外,要非常小心这种动态 sql 语句。即使您使用 cfqueryparam 保护所有 参数 ,查询仍然容易受到 sql 注入攻击,因为 myColumn
是用户提供的值。不幸的是,cfqueryparam 不能保护对象名称(table 名称、列名称等),只能保护文字(字符串、日期等)。因此,如果您绝对 必须 在原始 sql 中使用动态列名,请务必根据白名单验证它们,如果检测到无效列,则拒绝请求。
您可以使用以下方法。几年前我写了这个例程,当时我需要动态地建立一个 cfquerparams 数组。
我还添加了 'ReadQuery' 功能,以防万一,您将来需要使用它。
已在 Lucee 4.5 (Windows 2008R2) 和 ACF11 (Windows 10) 上进行了全面测试。
如果您需要有关调用 sysntax 的进一步说明,请告诉我,但我在底部添加了一个示例,以帮助您入门。
这些函数实际上是 CFC 服务的一部分,但您可以独立使用它们:
<!--- FUNCTION UDF: build SQL params --->
<!---
Notes:
Use for building sql with simple read queries:
Supported:
- INNER JOINS
- value paramaterization
- IN operator with or without paramaterization
- ignore WHERE clause item, if a certain value or a value in a list of values, is matched: {...'ignore'='value'}
- ignore value list custom delimeter: default {...'ignoredelimiter'=','}
- use {...'sqltype'='number|string'} for non value paramaterization
- positional paramaters 'table column ?'
Unsupported:
- subqueries
- named parameters, 'table column = :table column', due to a bug with the way Railo parses table prefixed columns sql
--->
<cffunction name="BuildSQLParams" access="public" returntype="string" hint="function description: build SQL params">
<cfargument name="query" required="false" default="#StructNew()#" type="struct" hint="argument description: query">
<cfargument name="params" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: params">
<cfset var result = "">
<cfset var local = StructNew()>
<cfset local.keylist = "column,operator,sqltype,value">
<cfset local.sqlarray = ArrayNew(1)>
<cfif IsStruct(arguments.query) AND ArrayLen(arguments.params)>
<cfloop from="1" to="#ArrayLen(arguments.params)#" index="local.i">
<cfset local.param = arguments.params[local.i]>
<cfif IsStruct(local.param) AND NOT StructIsEmpty(local.param)>
<cfset local.isValidParam = false>
<cfset local.counter = 0>
<cfloop collection="#local.param#" item="local.key">
<cfif ListFindNoCase(local.keylist,local.key)>
<cfset local.counter = local.counter + 1>
</cfif>
</cfloop>
<cfif local.counter EQ ListLen(local.keylist)>
<cfset local.isValidParam = true>
</cfif>
<cfif local.isValidParam>
<cfset local.ignore = false>
<cfset local.ignoredelimiter = ",">
<cfif StructKeyExists(param,'ignoredelimiter')>
<cfset local.ignoredelimiter = param['ignoredelimiter']>
</cfif>
<cfif StructKeyExists(param,'ignore')>
<cfif ListLen(param['ignore'],local.ignoredelimiter)>
<cfif ListFindNoCase(param['ignore'],param['value'],local.ignoredelimiter)>
<cfset local.ignore = true>
</cfif>
<cfelse>
<cfif param['ignore'] EQ param['value']>
<cfset local.ignore = true>
</cfif>
</cfif>
</cfif>
<cfif NOT local.ignore>
<cfif NOT ListFindNoCase("number,string",param['sqltype'])>
<cfif param['operator'] EQ "IN">
<cfset arguments.query.addParam(value=param['value'],cfsqltype="cf_sql_#param['sqltype']#",list="yes")>
<cfelse>
<cfset arguments.query.addParam(value=param['value'],cfsqltype="cf_sql_#param['sqltype']#")>
</cfif>
</cfif>
</cfif>
<cfif NOT local.ignore>
<cfsavecontent variable="local.sql">
<cfoutput>
#param['column']#
#param['operator']#
<cfif ListFindNoCase("number,string",param['sqltype'])>
<cfif param['sqltype'] EQ "number">
#param['value']#
<cfelse>
'#param['value']#'
</cfif>
<cfelse>
<cfif param['operator'] EQ "IN">
(?)
<cfelse>
?
</cfif>
</cfif>
<cfif StructKeyExists(param,'andOr')>
#param['andOr']#
</cfif>
</cfoutput>
</cfsavecontent>
<cfset result = result & local.sql>
</cfif>
</cfif>
</cfif>
</cfloop>
</cfif>
<cfif Len(Trim(result))>
<cfset result = REReplaceNoCase(result,"[\s]+"," ","ALL")>
<cfset result = REReplaceNoCase(result,"[\s]+(AND|OR|,)[\s]*$","","ALL")>
<cfset result = Trim(result)>
</cfif>
<cfreturn result />
</cffunction>
<!--- FUNCTION UDF: read query --->
<!---
Notes:
Use for executing sql with simple read queries:
Supported:
- query attributes: datasource
Unsupported:
- apart from 'datasource', no other query attributes are supported
--->
<cffunction name="ReadQuery" returntype="struct" output="false" access="public" hint="function description: read query">
<!--- arguments --->
<cfargument name="dsn" required="yes" hint="argument description: dsn">
<cfargument name="columns" type="string" required="no" default="" hint="argument description: columns">
<cfargument name="tables" type="string" required="no" default="" hint="argument description: tables">
<cfargument name="params" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: params">
<cfargument name="groupby" type="string" required="no" default="" hint="argument description: group by">
<cfargument name="orderby" type="string" required="no" default="" hint="argument description: order by">
<cfargument name="sortorder" type="string" required="no" default="ASC" hint="argument description: sort order">
<!--- local variables --->
<cfset var result = StructNew()>
<cfset var local = StructNew()>
<!--- logic --->
<cfset StructInsert(result,"query",QueryNew(''))>
<cfset StructInsert(result,"metaInfo",StructNew())>
<cfif Len(Trim(arguments.tables))>
<cfset local.wheresql = "">
<cfset local.groupby = "">
<cfset local.orderby = "">
<cfif Len(Trim(arguments.groupby))>
<cfset local.groupby = " GROUP BY " & arguments.groupby>
</cfif>
<cfif Len(Trim(arguments.orderby))>
<cfset local.orderby = " ORDER BY " & arguments.orderby & " " & arguments.sortorder>
</cfif>
<cfset local.query = new Query()>
<cfset local.query.setAttributes(datasource=arguments.dsn)>
<cfset local.query.setAttributes(name="result")>
<cfif ArrayLen(arguments.params)>
<cfset local.wheresql = BuildSQLParams(local.query,arguments.params)>
</cfif>
<cfif Len(Trim(local.wheresql))>
<cfset local.wheresql = " WHERE " & local.wheresql>
</cfif>
<cfset local.execute = local.query.execute(sql="SELECT #arguments.columns# FROM #arguments.tables##local.wheresql##local.groupby##local.orderby#")>
<cfset result.query = local.execute.getResult()>
<cfset result.metaInfo = local.execute.getPrefix()>
</cfif>
<cfreturn result>
</cffunction>
<!--- FUNCTION UDF: update query --->
<!---
Notes:
Use for executing sql with simple update queries:
Supported:
- query attributes: datasource
Unsupported:
- apart from 'datasource', no other query attributes are supported
--->
<cffunction name="UpdateQuery" returntype="struct" output="false" access="public" hint="function description: read query">
<!--- arguments --->
<cfargument name="dsn" required="yes" hint="argument description: dsn" />
<cfargument name="tables" type="string" required="no" default="" hint="argument description: tables">
<cfargument name="setparams" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: set params">
<cfargument name="whereparams" required="false" default="#ArrayNew(1)#" type="array" hint="argument description: where params">
<!--- local variables --->
<cfset var result = StructNew()>
<cfset var local = StructNew()>
<!--- logic --->
<cfset StructInsert(result,"query",QueryNew(''))>
<cfset StructInsert(result,"metaInfo",StructNew())>
<cfif Len(Trim(arguments.tables))>
<cfset local.setsql = "">
<cfset local.wheresql = "">
<cfset local.query = new Query()>
<cfset local.query.setAttributes(datasource=arguments.dsn)>
<cfset local.query.setAttributes(name="result")>
<cfif ArrayLen(arguments.setparams)>
<cfset local.setsql = BuildSQLParams(local.query,arguments.setparams)>
</cfif>
<cfif Len(Trim(local.setsql))>
<cfset local.setsql = " SET " & local.setsql>
</cfif>
<cfif ArrayLen(arguments.whereparams)>
<cfset local.wheresql = BuildSQLParams(local.query,arguments.whereparams)>
</cfif>
<cfif Len(Trim(local.wheresql))>
<cfset local.wheresql = " WHERE " & local.wheresql>
</cfif>
<cfset local.execute = local.query.execute(sql="UPDATE #arguments.tables##local.setsql##local.wheresql#")>
<cfset result.query = local.execute.getResult()>
<cfset result.metaInfo = local.execute.getPrefix()>
</cfif>
<cfreturn result>
</cffunction>
<cfset sqlarray = ArrayNew(1)>
<cfset wherearray = ArrayNew(1)>
<cfset ArrayAppend(sqlarray,{'column'='id','operator'='=','sqltype'='integer','value'='123','andOr'=','})>
<cfset ArrayAppend(sqlarray,{'column'='csp','operator'='=','sqltype'='integer','value'='5','andOr'=','})>
...
<cfset ArrayAppend(wherearray,{'column'='rec_id','operator'='=','sqltype'='integer','value'=id,'andOr'=''}>
<cfset UpdateQuery(dsn=application.datasource,tables="answers",setparams=sqlarray,whereparams=wherearray)>