首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迭代动态创建的表并将数据插入到SQL Server表中

迭代动态创建的表并将数据插入到SQL Server表中
EN

Stack Overflow用户
提问于 2013-03-15 23:25:31
回答 3查看 1.8K关注 0票数 0

我有一个在.html表单中动态创建的表,并且我想在.cfm表单中执行插入操作。我需要遍历动态创建的表的各行,并对SQL Server中的表执行插入操作。此外,该表是在JavaScript中创建的。谢谢。

代码语言: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代码:

代码语言:javascript
复制
<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);
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-15 23:49:00

首先,你的问题是什么?你收到错误了吗?你现在得到了什么结果--它们与你预期的有什么不同?

在不了解表单/数据结构的情况下,我通常建议在这种情况下使用唯一的表单字段名称。当您对多个字段使用相同的名称时,字段值将以逗号分隔列表的形式提交。当值本身包含逗号时,这可能会导致问题,因为无法确定一个值的结束位置和另一个值的开始位置。

要创建唯一的字段名称,请让javascript向每组字段追加一个计数器号。因此,这些字段将命名为:

  • FORM.GrandNum1,
    • FORM.GrandNum1,,台式机主板,FORM.sectCode1,主板,FORM.txtComments1,主板,
      • FORM.GrandNum1,FORM.GrandNme2,主板,FORM.sectCode2,主板,FORM.txtComments2,主板,...
      • FORM.GrandNum3,FORM.GrandNme2,主板,...` FORM.GrandNme3,主板,FORM.sectCode3,主板,FORM.txtComments3,主板,...`

然后将总数存储在隐藏字段中。在操作页面上,执行一个简单的from/to循环。如果需要,可以使用cfparam为可能不存在的任何字段(如复选框或单选按钮)设置默认值(文本字段始终存在)。然后,您可以使用cfqueryparamnull属性,它比isDefinedstructKeyExists IMO要干净一些。

代码语言:javascript
复制
    <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代码应该可以很好地工作。

代码语言:javascript
复制
    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" />

更新:

其他几点评论

  1. 在查询循环中不需要cfoutput。在处理用户提供的值以防止cfqueryparam注入时,将使用SQL值对变量进行求值。尤其是在循环时。cfqueryparam使用绑定变量,绑定变量不能在查询中使用DateFormat。它是为表示而设计的,并返回一个字符串。日期字符串可能会被误解,这取决于您的数据库设置。为避免歧义,请始终插入日期/时间对象,如now()而不是字符串。请参阅Matt's example及其对Date的用法
票数 1
EN

Stack Overflow用户

发布于 2013-03-15 23:30:26

您需要使用VALUES插入到数据库中。你也应该使用structKeyExists而不是isDefined,你也应该使用cfqueryparam。我也会给你的变量设置作用域。

代码语言:javascript
复制
<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>
票数 2
EN

Stack Overflow用户

发布于 2013-03-16 00:49:22

这是对其他两个答案的补充。我将把它限制在前面没有提到的两个主题上。

首先,有时将循环放在查询中比将查询放在循环中更有效。具体细节取决于您的数据库,但一种通用的方法如下:

代码语言:javascript
复制
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有一个空属性。以下是date数据类型的示例

代码语言:javascript
复制
<cfqueryparam = cfsqltype="cf_sql_date" value="#something#"
null = "#not isDate(something)#">

由于isDate在空字符串上返回false,这将导致在日期字段中插入空值,而不是使查询崩溃。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15436110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档