ColdFusion - 使用CFLOOP动态创建列名

时间:2010-10-12 20:51:02

标签: coldfusion coldfusion-8

我有一张表格,记录上传文件的名称,每条记录最多14张。这些列的名称如下:

TABLE tblDocuments
COLUMNS documentID (int, not null, pk)
        document1 (varchar(250), null)
        document2 (varchar(250), null)
        /* and this continues through */
        document14 (varchar(250), null)

所以我查询特定记录的任何文件:

<cfquery name="qryGetDocs" datasource="#dsn#">
     SELECT document1, ...document14
     FROM   tblDocuments
     WHERE  documentID = <cfqueryparam name="SESSION.documentID" cfsqltype="cf_sql_integer">
</cfquery>

表单看起来像这样:

<form name="frmUploadDocs" method="post" action="documentsPage.cfm">

<input type="file" name="document1" size="50" >
<cfif qryGetDocs.document1 IS NOT ''>
   (current file name: <a href="#vars.file_path#/#qryGetDocs.document1#">#qryGetDocs.document1#</a>)</cfif>

<input type="file" name="document2" size="50" >
<cfif qryGetDocs.document2 IS NOT ''>
   (current file name: <a href="#vars.file_path#/#qryGetDocs.document2#">#qryGetDocs.document2#</a>)</cfif>

<!--- list all documents --->

<input type="file" name="document14" size="50" >
<cfif qryGetDocs.document14 IS NOT ''>
   (current file name: <a href="#vars.file_path#/#qryGetDocs.document14#">#qryGetDocs.document14#</a>)</cfif>

<input type="submit" name="submit" value="Upload Documents">
</form>

我想从1循环到14,所以我只有一个<input><cfif>语句,如下所示:

<cfloop from="1" to="14" index="i">
   <input type="fiile" name="document#i#" size="30">
   <cfif qryGetDocs.document#i# IS NOT ''>
     (current file name: <a href="#vars.file_path#/#qryGetDocs.document[#i#]#">#qryGetDocs.document[#i#]#</a>)
   </cfif>
</cfloop>

但是,无论我尝试过什么,我都无法正确理解语法。有人可以帮我这个吗?谢谢!

2 个答案:

答案 0 :(得分:3)

(原来的问题已经回答了。但只是为了说明......)

更灵活的结构是将文档存储为行。所以基本表可能是:

TABLE:    tblDocuments
COLUMNS:  DocumentID  (unique record id)
          UserID
          DocumentName

使用此结构,您可以使用简单查询检索单个用户的所有现有文档

<cfquery name="qryGetDocs" datasource="#dsn#">
     SELECT documentID, documentName
     FROM   tblDocuments
     WHERE  userID = <cfqueryparam name="#SomeUserIDVariable#" cfsqltype="cf_sql_integer">
</cfquery>

..并使用简单的输出循环显示它们。 (注意,我将“documentID”添加为隐藏字段以标识现有文档。)

<cfoutput query="qryGetDocs">
   ...
   <input type="file" name="document#CurrentRow#" size="50" >
   <input type="hidden" name="documentID#CurrentRow#" value="#documentID#" >
   (current file name: <a href="#vars.file_path#/#documentName#">#documentName#</a>)
</cfoutput>

如果查询包含少于14个文件(或者无论你的最大值是多少......),你可以使用query.recordCount来确定多少个文件 要显示的其他文件输入。

<cfset nextInputNumber = qryGetDocs.recordCount + 1>
<cfoutput>
<cfloop from="#nextInputNumber#" to="#MaximumNumberOfDocs#" index="counter">
   <input type="file" name="document#counter#" size="50" >
   <input type="hidden" name="documentID#counter#" value="0" >
</cfloop>
</cfoutput>

答案 1 :(得分:2)

可以使用字符串索引和方括号访问查询(如结构),但前提是您还包含所需的行号(!)。这就像一个二维的阵列。

<cfloop from="1" to="14" index="i">
   <input type="file" name="document#i#" size="30">
   <cfif qryGetDocs["document#i#"][qryGetDocs.CurrentRow] IS NOT ''>
     (current file name: <a href="HTMLEditFormat("#vars.file_path#/#qryGetDocs["document#i#"][qryGetDocs.CurrentRow]#")#">#HTMLEditFormat(qryGetDocs["document#i#"][qryGetDocs.CurrentRow])#</a>)
   </cfif>
</cfloop>

请注意HTMLEditFormat()以防止跨站点脚本攻击。 这很重要!如果没有正确转义数据,永远不会将数据输出到HTML。 (我承认文件名是一个不太可能的攻击向量,因为它们通常不能包含尖括号,但是a)你不能太谨慎,b)这是一个很好的习惯,c)没有人知道什么是安全性当代码在将来的某个时刻重新计算时,会弹出漏洞。不是HTML转义的数据是不可原谅的邋。。)

更具惯用性和更易读的版本是:

<cfloop from="1" to="14" index="i">
   <cfset RowNum  = qryGetDocs.CurrentRow>
   <cfset ColName = "document#i#">
   <cfset DocName = qryGetDocs[ColName][RowNum]> 
   <cfset DocPath = "#vars.file_path#/#DocName#">
   <input type="file" name="#ColName#" size="30">
   <cfif FileExists(ExpandPath(DocPath))>
     (current file name: <a href="#HTMLEditFormat(DocPath)#">#HTMLEditFormat(DocName)#</a>)
   </cfif>
</cfloop>