Coldfusion 在查询中使用动态变量

Coldfusion 在查询中使用动态变量,coldfusion,coldfusion-9,cfquery,Coldfusion,Coldfusion 9,Cfquery,我有一个页面,其中输入字段的数量可变(该数量的字段保存在数据库中)。提交后,这些字段中的信息将保存到数据库中。字段的名称循环,当前循环编号附加到字段的末尾。然后我将其保存到一个变量中,并在查询中使用该变量。它从变量中获取正确的信息,但实际上并不计算表单字段。例如,表单字段中的值为: "#FORM.TEST_LOCATION_1#=two"<br> "#FORM.TEST_LOCATION_2#=four"<br> "#FORM.TEST_LOCATION_3#=six"&

我有一个页面,其中输入字段的数量可变(该数量的字段保存在数据库中)。提交后,这些字段中的信息将保存到数据库中。字段的名称循环,当前循环编号附加到字段的末尾。然后我将其保存到一个变量中,并在查询中使用该变量。它从变量中获取正确的信息,但实际上并不计算表单字段。例如,表单字段中的值为:

"#FORM.TEST_LOCATION_1#=two"<br>
"#FORM.TEST_LOCATION_2#=four"<br>
"#FORM.TEST_LOCATION_3#=six"<br>
"#FORM.TEST_LOCATION_4#=eight"<br>
"#FORM.TEST_LOCATION_5#=ten"<br>
"#FORM.TEST_NAME_1#=one"<br>
"#FORM.TEST_NAME_2#=three"<br>
"#FORM.TEST_NAME_3#=five"<br>
"#FORM.TEST_NAME_4#=seven"<br>
"#FORM.TEST_NAME_5#=nine"<br>
但不是将输入字段中实际输入的值放入数据库,而是放入:

"#form.test_location_1#"
"#form.test_location_2#"
"#form.test_location_3#"
"#form.test_name_1#"
"#form.test_name_2#"
"#form.test_name_3#"
etc
我现在使用的代码是:

 <cfset session.updque = ''>
    <cfloop from="1" to="#session.test_numfields#" index="numf">
      <cfset session.updque &= "test_location_" & #numf# &" = '##form.test_location_" & #numf# & "##', ">
      <cfset session.updque &= "test_name_" & #numf# &" = '##form.test_name_" & #numf# & "##', ">
    </cfloop>
    <cfquery DATASOURCE="#ODSN#" NAME="uptest" >  
      UPDATE redbook_test SET
        <cfoutput>#PreserveSingleQuotes(updque)#</cfoutput>
        test_date_last_mod='#datecompleted#',
        test_status='C', 
        where buildno = '#session.buildno#' 
    </CFQUERY>

更新红皮书测试集
#保留单引号(updque)#
测试(日期)上次(模式="日期完成",,
测试_status='C',
其中buildno='#session.buildno#'

我需要做什么才能真正将表单变量保存到数据库中???

form
是一个结构。要动态计算命名字段,请使用关联数组表示法:

        <cfset value = FORM["test_location_" & numf]>

此外,当您有多个名称相同的列时,即
test\u location\u 1
test\u location\u 2
,…,
location\u n
通常是您需要的一个好迹象。通常,您希望创建一个辅助表,并将复制的信息存储在行中,而不是列中,并返回到主表的链接。

这种语法将帮助您开始

update redbook_test
set test_date_last_mod <cfqueryparam value="#test_date_last_mod#">
, test_status='C'
<cfloop list="#form.fieldnames#" index="ThisField">
<cfif left(ThisField, 5) is "test_">
, #ThisField# = <cfqueryparam value = "#form[ThisField]#">
</cfif>
</cfloop>
where buildno = <cfqueryparam value='#session.buildno#'>
更新红皮书\u测试
设置测试日期最后一个模块
,test_status='C'
,#此字段#=
其中buildno=

它还不完整。你必须考虑如何处理空字符串、不同的数据类型等等。

输入字段的数量是如何变化的?页面上有一个按钮,每次单击时都会添加5个附加列。这个表单上可能有100个输入,我试图避免运行100次查询。这就是为什么我要先将所有数据保存到一个字符串中,然后在查询中使用该字符串。如果用户生成的表单字段多于您的列,会发生什么?暂时不要考虑数据库调用。如果需要的话,有一些方法可以将它们最小化。但是,从长远来看,表结构更为重要。您是说您正在根据单击的按钮数更改表并添加新列吗?如果是这样,那就不是一个好办法。首先,您最终将达到最大列数的限制。二是优化难度大,查询难度大。更好的方法是将数据存储在行中,而不是列中。我同意@Leigh的观点:如果可能的话,在考虑如何构建动态查询之前,请先修改这里的DB模式。即使在修复了语法错误之后,该示例也容易受到sql注入的影响。抱歉,但是-1.在修复语法错误后,这确实符合我的要求。谢谢你,丹。但就您的观点而言,Leigh,我完全理解您的意思,并将研究规范化表和删除漏洞。非常感谢!!我看到一些语法错误,但对提到的漏洞感到好奇。(将if更改为
将消除这种风险,尽管我同意继续修复数据库架构。)(1)此字段是用户提供的数据。(2) 您不仅要与用户打交道,还要与攻击者打交道;不要信任javascript内容。(3)
form[';drop tables']
是完全有效的CFML。(4) Left用于字符串,而不是变量名。(5) 当两个人告诉你某件事时,在回答之前写一些快速代码来测试你的假设
         UPDATE  Table
         SET     Column = <cfqueryparam value="#form.fieldName#" cfsqltype="...">
         WHERE   ...
update redbook_test
set test_date_last_mod <cfqueryparam value="#test_date_last_mod#">
, test_status='C'
<cfloop list="#form.fieldnames#" index="ThisField">
<cfif left(ThisField, 5) is "test_">
, #ThisField# = <cfqueryparam value = "#form[ThisField]#">
</cfif>
</cfloop>
where buildno = <cfqueryparam value='#session.buildno#'>