[英]Iterate through a dynamically created table and Insert data into SQL Server table
我有一个以.html格式动态创建的表,我想以.cfm格式进行插入。 我需要遍历动态创建的表的行,并对SQL Server中的表执行INSERT。 此外,该表是用JavaScript创建的。 谢谢。
<cfoutput>
<cfloop from="1" to="#ArrayLen(tblSample)#" index="i">
<cfquery name="AppendForm" datasource="TestSource">
INSERT INTO tblGrand
(GrandNum,
GrandName,
County,
VersionType,
VersionNum,
SectCode,
Comments,
Provider,
TypeID,
SubmitDate)
Select
<cfif isdefined("form.GrandNum")>
'#GrandNum#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.GrandNme")>
'#GrandNme#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.selCnty")>
'#selCnty#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.VersionType")>
'#VersionType#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.VersionNum")>
'#VersionNum#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.SectCode[i]")>
'#SectCode[i]#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.txtComments[i]")>
'#textComments[i]#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.txtProvider[i]")>
'#txtProvider[i]#',
<cfelse>
null,
</cfif>
<cfif isdefined("form.selType[i]")>
'#selType[i]#',
<cfelse>
null,
</cfif>
'#DateFormat(Now(),"yyyy-mm-dd") &" "& TimeFormat(Now(),"HH:mm:ss")#'
</cfquery>
</cfloop>
</cfoutput>
这是我创建表的html代码:
<script language="javascript" type="text/javascript">
function addRow() {
var tbl = document.getElementById('tblSample');
var lastRow = tbl.rows.length;
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
// left cell
var cellLeft = row.insertCell(0);
var textNode = document.createTextNode(iteration-3);
cellLeft.appendChild(textNode);
// select cell
var cellRightSel = row.insertCell(1);
var sel = document.createElement('select');
sel.name = 'sectCode' + iteration;
sel.id = 'sectCode' + iteration;
sel.options[0] = new Option('---Any---', '0');
sel.options[1] = new Option('Level 0.5: test1, '1');
sel.options[2] = new Option('Level I: test2', '2');
sel.options[3] = new Option('Level I.D: test3', '3');
sel.options[4] = new Option('Level II.1: test4', '4');
sel.options[5] = new Option('Level II.5: test5', '5');
cellRightSel.appendChild(sel);
var cellRights = row.insertCell(2);
var els = document.createElement('input');
els.type = 'text';
els.name = 'txtComments' + iteration;
els.id = 'txtComments' + iteration;
els.size = 20;
cellRights.appendChild(els);
var cellRight = row.insertCell(3);
var el = document.createElement('input');
el.type = 'text';
el.name = 'txtProvider' + iteration;
el.id = 'txtProvider' + iteration;
el.size = 20;
cellRight.appendChild(el);
var cell7 = row.insertCell(8);
var sel5 = document.createElement('select');
sel5.name = 'selType' + iteration;
sel5.id = 'selType' + iteration;
sel5.options[0] = new Option('---Any---', '---Any---');
sel5.options[1] = new Option('Fees, 'Fees);
sel5.options[2] = new Option('Reimbursement', 'Reimbursement');
cell7.appendChild(sel5);
}
您需要使用VALUES
插入数据库。 您还应该使用structKeyExists
而不是isDefined
并且也应该使用cfqueryparam
。 我也将范围变量。
<cfloop from="1" to="#ArrayLen(tblSample)#" index="i">
<cfquery name="AppendForm" datasource="TestSource">
INSERT INTO tblGrand
(GrandNum,
GrandName,
County,
VersionType,
VersionNum,
SectCode,
Comments,
Provider,
TypeID,
SubmitDate)
VALUES (
<cfif structKeyExists(form,"GrandNum")>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form.GrandNum#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"GrandNme")>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form.GrandNme#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"selCnty")>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form.selCnty#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"VersionType")>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form.VersionType#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"VersionNum")>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form.VersionNum#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"SectCode"&i)>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form['SectCode'&i]#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"txtComments"&i)>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form['textComments'&i]#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"txtProvider"&i)>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form['txtProvider'&i]#">,
<cfelse>
NULL,
</cfif>
<cfif structKeyExists(form,"selType"&i)>
<cfqueryparam cfsqltype="cf_sql_varchar" value="#form['selType'&i]#">,
<cfelse>
NULL,
</cfif>
<cfqueryparam cfsqltype="cf_sql_timestamp" value="#Now()#">)
</cfquery>
</cfloop>
首先,你要问什么? 您遇到错误了吗? 您现在得到什么结果-它们与您的预期有何不同?
在不了解您的表单/数据结构的更多信息的情况下,我通常建议在这种情况下使用唯一的表单字段名称。 当您对多个字段使用相同的名称时,字段值将以逗号分隔列表的形式提交。 当值本身包含逗号时,这可能会导致问题,因为无法确定一个值在何处结束而另一个在何处开始。
要创建独特的字段名,有你的JavaScript追加一个计数器数到每个字段集 。 因此这些字段将被命名为:
然后将总数存储在隐藏字段中。 在操作页面上,执行简单的“从/到”循环。 如果需要,请使用cfparam
为可能不存在的任何字段(例如复选框或单选按钮)设置默认值(文本字段始终存在)。 然后,您可以使用cfqueryparam
null
属性,它比IMO的isDefined
或structKeyExists
更干净。
<cfparam name="FORM.totalFields" default="0">
<cfloop from="1" to="#FORM.totalFields#" index="i">
<!--- extract current set of values --->
<cfset variables.txtComments = TRIM( FORM["txtComments"& i] )>
<cfset variables.sectCode = TRIM( FORM["sectCode"& i] )>
...
<cfquery name="AppendForm" datasource="TestSource">
INSERT INTO tblGrand (Comments, SectCode ....)
VALUES
(
<cfqueryparam cfsqltype="cf_sql_varchar" value="#variables.txtComments#" null="#not len(variables.txtComments)#">
, <cfqueryparam cfsqltype="cf_sql_varchar" value="#variables.sectCode#" null="#not len(variables.sectCode)#">
...
)
</cfquery>
</cfloop>
更新:
根据您的更新,您现有的代码与我上面最初描述的非常接近。 您只需要添加隐藏字段,并在每次添加行时对其进行更新。 然后,上面的cfloop代码应该可以正常工作。
function addRow() {
// removed extra variables
var tbl = document.getElementById('tblSample');
var row = tbl.insertRow(tbl.rows.length);
// use hidden value to calculate total fields
var iteration = parseInt(document.getElementById('totalFields').value) + 1;
var cellLeft = row.insertCell(0);
var textNode = document.createTextNode(iteration);
... etcetera ...
// save new total
document.getElementById('totalFields').value = iteration;
}
...
<input type="hidden" id="totalFields" name="totalFields" value="0" />
更新:
其他一些评论
cfoutput
。 变量将自动评估 cfqueryparam
来防止sql注入。 特别是在循环时。 cfqueryparam
使用绑定变量,这些变量可以“多次执行cfquery语句时提高性能 ”。 DateFormat
。 它是为演示而设计的,并返回一个字符串。 日期字符串可能会误解,具体取决于您的数据库设置。 为避免歧义,请始终插入日期/时间对象,例如now()
而不是字符串。 请参阅Matt的示例及其对now()
用法。 这是对其他两个答案的补充。 我将其限制为前面未提到的两个主题。
首先,有时将循环放在查询中比将查询放入循环更有效。 详细信息取决于您的数据库,但是一种通用的实现方式是这样的:
insert into yourtable
(field1, field2, etc)
select null, null, etc
from SomeSmallTable
where 1 = 3
<cfloop>
union
select #value1#, #value2#, ect
from somesmalltable
</cfloop>
在sql server中,您不需要“ from SomeSmallTable”。 在mysql中,您可以使用values关键字,并且仍然使用循环。
由于多种原因,该方法不适用于大量记录,但值得一提。
接下来,您可能需要应对空白表单字段。 对于不能简单地插入空字符串的数字和日期字段尤其如此。 好消息是cfqueryparam具有null属性。 这是日期数据类型的示例
<cfqueryparam = cfsqltype="cf_sql_date" value="#something#"
null = "#not isDate(something)#">
由于isDate在空字符串上返回false,因此这将导致将null值插入到日期字段中,而不会导致查询崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.