0

動的に作成された.htmlフォームのテーブルがあり、.cfmフォームに挿入したいと思います。動的に作成されたテーブルの行をループして、SQLServerのテーブルに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);
}
4

3 に答える 3

2

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>
于 2013-03-15T15:30:25.910 に答える
1

まず、あなたの質問は何ですか?エラーが発生していますか?あなたが今得ている結果は何ですか?そしてそれらはあなたが期待したものとどのように異なりますか?

フォーム/データ構造について詳しく知らなくても、この場合は通常、一意のフォームフィールド名を使用することをお勧めします。複数のフィールドに同じ名前を使用する場合、フィールド値はコンマ区切りのリストとして送信されます。一方の値がどこで終わり、もう一方の値がどこで始まるかを判断する方法がないため、値自体にコンマが含まれている場合、問題が発生する可能性があります。

一意のフィールド名を作成するには、JavaScriptで各フィールドセットにカウンター番号を追加してもらいます。したがって、フィールドには次の名前が付けられます。

  • FORM.GrandNum1、FORM.GrandNme1、FORM.sectCode1、FORM.txtComments1、..。
  • FORM.GrandNum2、FORM.GrandNme2、FORM.sectCode2、FORM.txtComments2、..。
  • FORM.GrandNum3、FORM.GrandNme3、FORM.sectCode3、FORM.txtComments3、... `

次に、合計数を非表示フィールドに保存します。アクションページで、単純なfrom/toループを実行します。必要に応じて、cfparamチェックボックスやラジオボタンなどの存在しない可能性のあるフィールドのデフォルト値を設定するために使用します(テキストフィールドは常に存在します)。次に、またはIMOよりも少しクリーンなnull属性を使用できます。cfqueryparamisDefinedstructKeyExists

    <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" />

アップデート:

他のいくつかのコメント

  1. cfoutputクエリループを回避する必要はありません。変数は自動的に評価されます
  2. cfqueryparamSQLインジェクションを防ぐために、ユーザー指定の値を処理する場合は常に使用してください。特にループするとき。「cfqueryステートメントを複数回実行するときのパフォーマンスを向上させる」ことcfqueryparamができるバインド変数を使用します。
  3. DateFormatクエリでは使用しないでください。プレゼンテーション用に設計されており、文字列を返します。データベースの設定によっては、日付文字列が誤って解釈される可能性があります。あいまいさを避けるために、常に日付/時刻オブジェクト、つまりnow()文字列ではなくlikeを挿入してください。マットの例と彼の使用法を参照してくださいnow()
于 2013-03-15T15:48:59.653 に答える
0

これは他の2つの答えに追加されます。これまでに言及されていない2つのトピックに限定します。

まず、クエリをループ内に配置するよりも、ループをクエリ内に配置する方が効率的な場合があります。詳細はデータベースによって異なりますが、一般的な方法の1つは次のとおりです。

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サーバーでは、「fromSomeSmallTable」は必要ありません。mysqlでは、valuesキーワードを使用しても、ループを使用できます。

この方法は、さまざまな理由で非常に多くのレコードでは機能しませんが、説得する価値があるかもしれません。

次に、空白のフォームフィールドと戦わなければならない場合があります。これは、空の文字列を単純に挿入できない数値フィールドと日付フィールドに特に当てはまります。幸いなことに、cfqueryparamにはnull属性があります。日付データ型の例を次に示します

<cfqueryparam = cfsqltype="cf_sql_date" value="#something#"
null = "#not isDate(something)#">

isDateは空の文字列に対してfalseを返すため、クエリをクラッシュさせるのではなく、null値が日付フィールドに挿入されます。

于 2013-03-15T16:49:22.487 に答える