Looping over the query results set - coldfusion

I am checking with some work where i am geting the query result as:
query
VALUE
1 #FF6600,#339933,#0033CC,#FF0000,#00CC66,#FF9900,#FFFF00,#00FFFF,#FF66FF
2 Open, Resolved, In-Progress, Escalated, Closed, Re-Opened,Rejected,On-Hold,Locked
Now i need to map the 1st row parrallel value to the 2row, I know that this can be done via cfloop or like should i convert it with Array..
Need nested loops, but not sure how it will work
please guide

Something like this should work for the data in your question.
<cfset NumberOfItems = ListLen(queryname.value[1])>
<cfoutput>
<cfloop from=1 to=NumberOfItems index=idx>
Row 1 item is #ListGetAt(queryname.value[1], idx)#<br>
Row 2 item is #ListGetAt(queryname.value[2], idx)#<br>
</cfloop>
</cfoutput>

Related

ColdFusion cfloop issue

I'm running ColdFusion 2016. I have a cfloop which pulls in data from a query, all other ColdFusion queries work fine on the page and if I pull in the same variable in an output outside the loop, it works fine, except the loop is giving me an error. The error output says:
Variable GPS_LATITUDE is undefined.
Which is correct, as in the database there is no GPS_LATITUDE but there is a GPS_LATITUDE1.
I need to add the loop number on the end of the variable so as it loops pulls in the data gps_latitude1, gps_latitude2, gps_latitude3 not just gps_latitude.
My loop code is...
<cfoutput>
<cfloop index="i" from="1" to="3">
<td><p>#gps_latitude[i]#</p></td>
<td><p>#gps_longitude[i]#</p></td>
</cfloop>
</cfoutput>
Any guidance much appreciated.
#elixieru, You can't directly give gps_latitude[i]. which is not check your query which is consider it as Array. I can imagine your scenario and give my sample code about how to get an same columnName with
<cfquery name='test' datasource="mytest">
select * from test
</cfquery>
This is my sample query. It's having column name as address1, address2 etc... I'm going to get the data about address1 & address2 like your scenario.
<cfloop query="test">
<cfloop from="1" to="2" index="i">
<cfset a = test["address#i#"]>
<cfoutput> #a# </cfoutput> <br/>
</cfloop>
</cfloop>
Here I'm looping over the query and so some simple / index loop based on my count ( Address1,2,3,4,5 etc ). For now I'm just use 2 like from 1 to 2.
Here I've store the test['address#i#'] in variable a and print that variable. Now test['address#i#'] it will consider as test.address1
I hope my sample help you more.

ColdFusion ListAppend

I am having difficulties trying to use ListAppend.
I have data from a table and this is my code.
<cfquery name="getData" datasource="test">
select * from test;
</cfquery>
Now what I want to do is to make all the values in the column name which I have named it as nm_column into a list using ListAppend.
<cfset dataList = ListAppend('', '#getData.nm_column#')>
<cfoutput>#dataList#</cfoutput>
What this does is that it only shows the 1st value of the nm_colum. I do understand that I am missing the loop part, thats why its only showing me just the 1st value. So how do I loop it and get all the values to it?
I tried this, but it did not work.
<cfset dataList = ListAppend('', '<cfloop query="getData">#getData.nm_column#</cfloop>')>
So can someone please teach me the way to properly write that code?
There's a built in function in ColdFusion that will do this for you.
<cfset dataList = valueList(getData.nm_column)>
As far as the issue with your code, listAppend's first argument is the list you're adding things to. Also, you cannot nest ColdFusion tags like that. The code will not compile.
If you want to loop through something to append to a list, this is what you would do.
<cfset dataList = ''>
<cfloop query="getData">
<cfset dataList = listAppend(dataList, nm_column)>
</cfloop>
This would be terrible for performance though since a string is immutable. If you really needed to add items to a list through a lip I would create an array and then use arrayToList to convert that array to a list.

ColdFusion 11 DateFormat

I am moving one of our applications from ColdFusion 9.01 to ColdFusion 11 and encountered a situation where I cannot get the date formatted the way I want it using "DateFormat". I read through the docs since things have changed in CF versions, but I honestly can't figure out why this isn't working. It worked beautifully in CF 9. I know it's probably something very easy, but I am just not seeing it.
The query (Oracle DB) provides me a list of the last 30 days and the loop is simply to reformat the date output from "2014-07-01 00:00:00.0" to a more friendly looking display of 01-Jul-2014 except that I cannot get it to format as "dd-mmm-yyyy" it just spits back the original output from the query. I hard coded the date where normally there would be a cfquerparam. Any ideas?
<cfquery name="qryDateArray" datasource="#request.db#">
select trunc(to_date('07/01/2014', 'mm/dd/yyyy') + 1 - rownum) as ref_date
from dual connect by rownum <= 30
</cfquery>
<cfloop from="1" to="#qryDateArray.recordcount#" index="j">
<cfset qryDateArray.ref_date[j] = DateFormat(qryDateArray.ref_date[j], "dd-mmm-yyyy")>
</cfloop>
<cfoutput>
<cfdump var="#qryDateArray#">
</cfoutput>
I could not test this on CF11 since I do not have it handy. I did verify that your code though returns results as you explained when I ran it on my CF10 environment here. So what you can do is add a column to the query object and define it as a varchar and add your formatted data to that. This in turn dumped out the formatted dates.
<cfquery name="qryDateArray" datasource="#request.db#">
select trunc(to_date('07/01/2014', 'mm/dd/yyyy') + 1 - rownum) as ref_date
from dual connect by rownum <= 30
</cfquery>
<cfset aryData = [] />
<cfloop from="1" to="#qryDateArray.recordcount#" index="j">
<cfset ArrayAppend(aryData, DateFormat(qryDateArray.ref_date[j], "dd-mmm-yyyy")) />
</cfloop>
<cfset QueryAddColumn(qryDateArray, "STRDATE", "VarChar", aryData) />
<cfoutput>
<cfdump var="#qryDateArray#">
</cfoutput>
If dependent on the query column names then could use something like Ben's method explained here to do some renaming of the columns: http://www.bennadel.com/blog/357-ask-ben-changing-coldfusion-query-column-names.htm
It'd be great if you'd given us a portable test case rather than one that relies on your database, but I suspect it is because ColdFusion has become more rigid with its type management of query columns.
So CF considers your ref_date column to be of type date, so when you try to put the formatted string back into the query column, CF tries (and succeeds) to convert the string back into a date.
Aside:
I have to wonder why you don't format the data string in the DB from the outset, and just return it the way you need it, rather than returning something else, then looping over the thing to adjust it..?

How to check for a null value from the return value in ColdFusion query loop

<cfloop query="GET_ALL_STUDENTS>
<cfif #student_id# is NOT NULL>
<!--- do something--->
</cfif>
</cfloop>
Above is how I am looping my cf query which returns null value and I want to check if the student_id is null or not. This is what I have tried and it failed. Can anyone tell me a better way?
You can use your database's ifNull() or the like. However, in ColdFusion, queries are returned as strings. Given your situation, easiest way is to check for a non-empty string:
<cfif len(student_id)>
By the way, you don't need the pound signs inside of an evaluation: only when using a variable as a literal (such as when outputting)
In Adobe ColdFusion 9, you can do:
<cfif IsNull(student_id)>
</cfif>
Or since you're doing the opposite:
<cfif NOT IsNull(student_id)>
</cfif>
It looks like the query is retrieving all of the students and then cfloops over the records to find the student_id fields that are NULL.
It would be more efficient to write a query that specifically queried the records that have student_id IS NULL.
The method of grabbing all the student table records will work great when you have 100 or so students. What happens when it is put into production and there are 25,000 students?
While the java class of CFQuery object (coldfusion.sql.QueryTable) will return empty string for any null value, it's parent class coldfusion.sql.Table is providing a method getField(row, column) to access the query table values directly, which return "undefined" if the value is null. We can make use of the IsNull to identify the "undefined" hence able to detect NULL.
<CFLOOP query="GET_ALL_STUDENTS">
Row = #CurrentRow#
<CFIF IsNull(GET_ALL_STUDENTS.getField(GET_ALL_STUDENTS.CurrentRow, GET_ALL_STUDENTS.findColumn('student_id')))>
[NULL]
<CFELSE>
#GET_ALL_STUDENTS.student_id#
</CFIF>
<br>
</CFLOOP>
Reference: http://laxmanthota.blogspot.com/2010/11/cfquery-and-underlying-java-objects.html

Only show if item is not most recent?

So we have a news/announcement function that pulls info from a database and displays it
<cfquery name="announcement" datasource="#application.datasource#" dbtype="odbc">
SELECT top 2 * FROM NewsEvents
WHERE type = 2 AND active = 1 AND publish_datetime <= #now()# AND show_on_home = 1 AND item_datetime >= #createOdbcDate(now())#
ORDER BY item_datetime ASC
</cfquery>
What we're trying to do is display a piece of HTML within these announcement blocks, conditional on one of the two blocks NOT being the most recent of the two blocks.
The HTML is wrapped in this code:
<cfif announcement.recordCount gt 0>
<cfloop query="announcement">
<cfoutput>
html
</cfoutput>
</cfloop>
<cfelse>
<cfoutput><p>There are currently no announcements.</p></cfoutput>
</cfif>
I want one component of the HTML to only be displayed for the BOTTOM announcement, the one that is not the closest in item_datetime. Any thoughts on how to accomplish this?
You're ordering by date, so just do something like this:
<cfif CurrentRow EQ 1>
We're showing the first record, so show some stuff.
</cfif>
CurrentRow is always available in a loop to show you which record of the query you're currently on. So given your current query (and some made up data straight outta my head, you'll end up with this output:
Record 1: August 29, 2011
We're showing the first record, so show some stuff
Record 2: August 30, 2011
You're sorting by the date ASC, so the oldest record is first, while the newer record is last. I would recommend that you change your sorting to DESC, or you're never going to get newer records once you've added a third announcement after the first two. You could then resort them on the CF side to be in the display order you're after.
You can add a modifier to your CFQUERY statement like so. I would also modify your CFIF recordCount statement to look for more than 1 record at this point.
<cfif announcement.recordCount gt 1>
<cfoutput query="announcement" startRow="2">
<!--- Throw my output here --->
</cfoutput>
<cfelse>
<p>There are currently no announcements.</p>
</cfif>