views:

550

answers:

1

CF8 and MySQL5, for loop within INSERT INTO.

I am getting form data and trying to optimize an insert statement to loop within the cfquery. The best case scenario would be that the loop is just around the VALUES in order to have a single INSERT, but I had issues in trying to ID the second iteration and put a comma at the beginning of the first INSERT VALUES. So I went with looping over the entire INSERT. At least that's within the same cfquery. My problem is that I can't get the syntax correct for the 2nd (and beyond) iterations of the loop. It works fine for the first one, and works fine if I take the loop out.

The error I get is:

sql syntax error near 'INSERT INTO table(wID,session,xNameVar,xID,set1rt,set2rt,set3rt,set4rt,set5rt,set'

Here is the code I use code:

<cfif structKeyExists(form, "x1s1xID")><!--- verifies if there is data in field 1 for a specific form section--->
  <cfquery name="qCreateXdata" datasource="#application.datasource#">
    <cfloop from="1" to="#form.sessions#" index="i"><!--- form.sessions is a variable for the number of times to loop --->
      <cfif structKeyExists(form, "x1s#i#xID")><!--- a little redundant but used for other iterations of loop otherwise get a variable not defined error --->
      INSERT INTO table
        (wID,
        session,
        xNameVar,
        xID,
        set1rt,
        set2rt,
        set3rt,
        set4rt,
        set5rt,
        set6rt)
      VALUES
        (#variables.wID#,
        #wCreateFormData["session" & i]#,
        '#wCreateFormData["x1s" & i & "xNameVar"]#',
        #wCreateFormData["x1s" & i & "xid"]#,
        <!--- the below values are not required in form so need to be null integers instead of empty strings if not set in form --->
        <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x1set1reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x1set1r" & i]))#" />,
        <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x1set2reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x1set2r" & i]))#" />,
        <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x1set3reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x1set3r" & i]))#" />,
        <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x1set4reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x1set4r" & i]))#" />,
        <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x1set5reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x1set5r" & i]))#" />,
        <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x1set6reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x1set6r" & i]))#" />
        )
        <cfif structKeyExists(form, "x2s#i#xID")>
            ,(#variables.wID#,
            #wCreateFormData["session" & i]#,
            '#wCreateFormData["x2s" & i & "xNameVar"]#',
            #wCreateFormData["x2s" & i & "xid"]#,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x2set1reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x2set1r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x2set2reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x2set2r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x2set3reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x2set3r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x2set4reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x2set4r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x2set5reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x2set5r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x2set6reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x2set6r" & i]))#" />
            )
        </cfif>
        <cfif structKeyExists(form, "x3s#i#xID")>
            ,(#variables.wID#,
            #wCreateFormData["session" & i]#,
            '#wCreateFormData["x3s" & i & "xNameVar"]#',
            #wCreateFormData["x3s" & i & "xid"]#,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x3set1reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x3set1r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x3set2reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x3set2r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x3set3reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x3set3r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x3set4reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x3set4r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x3set5reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x3set5r" & i]))#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#trim(wCreateFormData["x3set6reps" & i])#" maxlength="3" null="#NOT len(trim(wCreateFormData["x3set6r" & i]))#" />
            )
        </cfif>

        <!---... you get the idea.....there are 12 total cfif blocks like this --->
        <!--- then I end with a ';' in order to close this INSERT statement and go back to the start of the loop for #form.sessions# number of times --->

        ;
      </cfif>
    </cfloop>
  </cfquery>
</cfif>
+2  A: 

I believe this could replace your entire code:

<cfset i_max = 6>

<cfloop from="1" to="#form.sessions#" index="s">
  <!--- do all the 12 blocks you speak of --->
  <cfloop from="1" to="12" index="x">
    <cfif StructKeyExists(form, "x#x#s#s#xID")>

      <cfquery name="qCreateXdata" datasource="#application.datasource#">
        INSERT INTO table (
            wID,
            session,
            xNameVar,
            xID,
          <cfloop from="1" to="#i_max#" index="i">
            set#i#rt
            <cfif i lt i_max>,</cfif>
          </cfloop>
          ) VALUES (
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#variables.wID#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#wCreateFormData["session" & s]#" />,
            <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#wCreateFormData["x#x#s#s#xNameVar"]#" />,
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#wCreateFormData["x#x#s#s#xID"]#" />,
          <cfloop from="1" to="#i_max#" index="i">
            <cfqueryparam 
              cfsqltype = "CF_SQL_INTEGER" 
              value     = "#Trim(wCreateFormData["x#x#set#i#reps" & s])#" 
              maxlength = "3" 
              null      = "#Len(Trim(wCreateFormData["x#x#set#i#r" & s])) = 0#" 
            />
            <cfif i lt i_max>,</cfif>
          </cfloop>
          )
        ;
      </cfquery>

    </cfif>
  </cfloop>
</cfloop>

Hint: Do less copy-and-paste programming, try to find more abstractions for repetitive patterns. ;-) Doing essentially the same thing twelve times in a row by copy and paste should set off a big red alarm.

Tomalak
I agree. I got lazy with this since I was trying to balance an optimal schema with normalization and the number of nulls.
JS
You got me 99% of the way there. Much thanks and gratitude and I appreciate the lesson!
JS