CFLoop Error For Missing Entries

2019-03-06 07:56发布

问题:

please disregard this post. I have made a clearer example of my problem here: Error with CFLoop When Entries Are Missing

I am running the CFLoop code below.

<cfset data = queryNew("sid,firstname,lastname,age","integer,varchar,varchar,integer")>
<cfloop index="x" from="1" to="50">
    <cfset queryAddRow(data)>
    <cfset querySetCell(data,"sid",x)>
    <cfset querySetCell(data,"firstname","#first[x]#")>
    <cfset querySetCell(data,"lastname","#last[x]#")>
    <cfset querySetCell(data,"age","#studentage[x]#")>
</cfloop>

<cfoutput query="data">
    #sid# -  #firstnamet# #lastname# - #age#<br />
</cfoutput>

The variables first[x], last[x], and studentage[x] are being pulled from an external datasource, with X being the loop index. Note that the CFLoop has 50 entries.

When there is data available, the code works beautifully. However, when there is missing data, the code breaks. By that I mean if Entry 11 doesn't have a name listed for the first[x] variable I get an error along the lines of "Element first is undefined. The error occurred on line 5

(line 5 is the entry for first name).

When this happens, I would like to omit entry 11 (and all other entries which cause an error) from my results and prevent the error from showing. How can I do this?

Clarification: Please assume the data is defined. It gets a bit hairy since I am using an external datasource. But what I am saying is that Entries 1 to 10 show up. When its entry 11's turn, that's when the error comes up.

回答1:

Using the recordcount of the external database in the loop should prevent the errors.

<cfloop index="x" from="1" to="#ExternalDatabaseQuery.RecordCount#">

A better solution, assuming you do have the query in memory, would be to use a query of queries.

<cfquery dbtype='query' name='data'>
SELECT SID, First AS FirstName, Last AS LastName, Age AS StudentAge
FROM ExternalDatabaseQuery
</cfquery>


回答2:

Mike, apologies if I'm misunderstanding what you're after but it would seem that some basic conditionals could do the job. The following edit to your code is just a suggestion as to how to go about it (your full code base may dictate something slightly different, of course).

<cfset data = queryNew("sid,firstname,lastname,age","integer,varchar,varchar,integer")>
<cfloop index="x" from="1" to="50">
    <cfif isDefined("first[x]") AND isDefined("last[x]") AND isDefined("studentage[x]")>
    <cfset queryAddRow(data)>
    <cfset querySetCell(data,"sid",x)>
    <cfset querySetCell(data,"firstname","#first[x]#")>
    <cfset querySetCell(data,"lastname","#last[x]#")>
    <cfset querySetCell(data,"age","#studentage[x]#")>
    </cfif>
</cfloop>

<cfoutput query="data">
    #sid# -  #firstnamet# #lastname# - #age#<br />
</cfoutput>

The primary problem here (and maybe this is not an issue for you) is that this will output 50 - errors. So, if there are 3 errors (i.e., no data found) you'll have 47 entries output rather than 50. If that's an issue, please add a comment ... there are some alternative approaches for ensuring that you always have 50 items output.