views:

761

answers:

5

Hi All,

I am working on a CF site and need to get data from MySQL tables.

I can create the CFQuery fine and check for records returned, but how do I take the records returned and loop through them and get data from specific fields in each row.

I can write while if/end if, etc, I just dont recall how to get access to the data.

-JAson

+9  A: 

Assuming you made a query called the_query with a firstname column:

<cfoutput query="#the_query#">
   #firstName# ... etc <br>
</cfoutput>
Sam Farmer
Awesome, so that will output the data from the column. Perfect.If I wanted to assign the values from the column to variables to manipulate, etc, do I still use CFOUTPUT to get access to the columns?
I would highly recommend using CFLOOP instead of CFOUTPUT, and then wrap whatever logic/variables that are outputting to the browser in a CFOUTPUT
Adam
@Jason: If you just assigning values you just need to use cfset variableName = firstName. You can use cfloop for this, however, if you want to take advantage of the grouping feature of cfoutput (the group attribute) use cfoutput.
Sam Farmer
A: 

once you've defined your query within a CFQUERY, you would put your results inside a CFOUTPUT tag. You would specify the fields to display using the syntax #[query name].[field name]#.

abramN
+5  A: 

Alternately, you can use the CFLOOP tag to similar effect

Say for example you wanted to sum the "price" field for those rows which have a quantity greater than zero. (imagine a shopping cart)

<CFSET TOTAL=0>
<CFLOOP QUERY="the_query">
    <CFIF quantity gt 0>
        <CFSET TOTAL=TOTAL+PRICE>
    </CFIF>
</CFLOOP>

By the way, the use of hash marks/pound signs/octothorpes is discouraged in the CFOUTPUT Query parameter

[edit:] To dump the contents of the query stack add to [cf_root]\wwwroot\WEB-INF\debug.cfm before the "<!--- :: CFTimer :: --->" line:

<CFIF IsDefined("DumpQueries") >
    <cfset DQ_Queries= QueryToArray( CFDEBUG_QUERIES ) />  
    <CFLOOP From="1" to ="#CFDEBUG_QUERIES.recordcount#" index="i">
     <CFSET DQ_Queries[i].BODY =  DQ_Queries[i].BODY >
     <CFSAVECONTENT Variable="dump_content">
     <CFDUMP Var="#DQ_Queries[i]#" Expand="NO" Label="#DQ_Queries[i].NAME#">
     </CFSAVECONTENT>
     <CFOUTPUT>#REReplaceNoCase(dump_content,"expand"">BODY</td>[[:space:]]*<TD>[[:space:]]*","expand"">BODY</td><td><PRE>")#</CFOUTPUT>  
    </CFLOOP>
</CFIF>
Michael MacDonald
Sorry a little dense, if # is discouraged, how do I specify the columns from the table that I want? I dont think I know any other way since CF 2!
I was referring to another answer in this set. I recommend using <cfoutput query="the_query"> instead of <cfoutput query="#the_query#">Inside the actual begin/end cfoutput tags, then of course you would need to use them. ie <cfoutput query="the_query">#the_field#</cfoutput>
Michael MacDonald
OK, do you know how to take a CFQUERY after I build it up and echo what SQL it is running? I am not getting what I expect and want to make sure my SQL is in order.
There are a couple of ways of doing it. 1) create the sql as a variable and execute it <CFSET theSql="select *...."><CFQUERY Name="theQuery">#theSql#</CFQUERY><CFOUTPUT>#theSQL#</CFOUTPUT>or 2) use the internal undocumented functions: search for getDebuggingService().getDebugger().getData()
Michael MacDonald
I have actually modified our internal cfdebug page ( [cf_root]\wwwroot\WEB-INF\debug.cfm ) to check for a hidden parameter to dump the queries on an as needed basis.
Michael MacDonald
use <CFDUMP VAR="#the_query#"> to see what you have to work with in the result set
Adam
You can also see the query that's executing by turning on Request Debugging Output in the CF Administrator, and check the option under the debugging settings to show SQl. This will show you every query being run on the page, with parameters, etc.
RaeLehman
+2  A: 

There are a number of ways to do this. as noted above, you can use cfoutput with the query attribute. You can also reference 'queryname.columnname'.

If you need to access a specific row/column, you can use array notation as such:

queryname.columnname[rownum]

(remember, CF counts from 1, not 0). For dynamic column access, you can use

queryname[columnvariable][rownum]

If your columname is an illegal variable name in CF (like 8thCol) you can modify this a bit:

queryname['8thCol'][rownum]

Hope that helps.

Ben Doom
so if I use queryname.column do I use CFOUTPUT? so this:<cfquery name="getContent" datasource="#application.dsn#"> SELECT queryName, title, content FROM content WHERE queryName = #URL.queryName#; </cfquery> xxx = getContent.content
CFOUTPUT is only required if you want to output to the browser. CFOUTPUT with the query attribute is used for looping over the query to ooutput to a browser. You do not need it to do a cfset to set a variable for manipulation.
Ben Doom
+7  A: 

All the existing answers/comments seem to touch on different aspects, so this is an attempt to consolidate all this information into one clear explanation.
(This answer is set to community wiki - please edit as appropriate.)


To access a variable from a query, use:

QueryName.ColumnName[RowNum]
QueryName["ColumnName"][RowNum]

These will both work at any point after the query is created.
Both can be used inside cfoutput to display the variable, or inside cfset to assign the variable.

The second one is useful for dynamic variables, and can accept variables like so:

QueryName[DynamicColumnName][RowNum]
QueryName["Partial#DynamicName#"][RowNum]
QueryName["Partial"&DynamicName][RowNum]


As a convenience, instead of looping through a query manually:

<cfloop index="CurrentRow" from="1" to="#QueryName.RecordCount#">
    <cfoutput>#QueryName.ColumnName[CurrentRow]#</cfoutput>
</cfloop>

You can simply do:

<cfloop query="QueryName">
    <cfoutput>#QueryName.ColumnName[CurrentRow]#</cfoutput>
</cfloop>

And as a further shortcut, you can do:

<cfoutput query="QueryName">
    #QueryName.ColumnName[CurrentRow]#
</cfoutput>

And, when inside a <cfloop query=""> or a <cfoutput query=""> you can simply do:

<cfoutput query="QueryName">
 #ColumnName#
</cfoutput>

However, this last shortcut is only for display - if you do:

<cfset ColumnName = "NewValue" />

This will not modify the original query data. Instead, you need to do:

<cfset QueryName.ColumnName[CurrentRow] = "NewValue" />

And that will modify the results of the query (but not the value in the database).


To display the actual SQL query that has been run, with CF8 (also Railo and OpenBD), you can do:

<cfdump var="#QueryName#"/>

And it will show you both the results of the query and the actual SQL which has been run.

To display the actual SQL with CF7, you need to add a result="QueryInfo" to your cfquery tag, then <cfdump var="#QueryInfo#"/> will show you the SQL.

Peter Boughton