Making ColdFusion's QueryNew() More Readable

Posted December 4, 2006 at 2:08 PM

Tags: ColdFusion

The ability to manually create, query, and manipulate ColdFusion record sets is one of the best features of ColdFusion. Maybe, I am crazy, but ColdFusion query of queries are just the cat's pajamas! Some times, as in today, I use the QueryNew() function to create rather large queries. As you know, the QueryNew() method takes two arguments: the query column names and the query column types. As you can imagine, the bigger the query (number of columns) the harder and harder it becomes to see which column types apply to which columns. To remedy this, I have come up with a simple solution to map the column names to column types in a highly readable way:

 Launch code in new window » Download code as text file »

  • <!--- Create the columns definitions for query new. --->
  • <cfsavecontent variable="strColumns">
  • data :: VARCHAR,
  • rfid :: VARCHAR,
  • date :: VARCHAR,
  • time :: VARCHAR,
  • gross :: VARCHAR,
  • tare :: VARCHAR,
  • net :: VARCHAR,
  • level :: VARCHAR,
  • rollover_id :: VARCHAR,
  • rb_dollars :: DECIMAL,
  • is_valid :: INTEGER,
  • is_invalid_account :: INTEGER,
  • is_invalid_entry :: INTEGER,
  • is_invalid_gross :: INTEGER,
  • is_invalid_tare :: INTEGER,
  • is_invalid_net :: INTEGER,
  • is_duplicate_credit :: INTEGER,
  • useraccount_id :: VARCHAR,
  • rfid_count :: VARCHAR,
  • address_id :: VARCHAR,
  • street1 :: VARCHAR,
  • street2 :: VARCHAR,
  • city :: VARCHAR,
  • state :: VARCHAR,
  • zip :: VARCHAR
  • </cfsavecontent>
  •  
  • <!---
  • Manually create a query using the column mapping
  • defined in the CFSaveContent tag above.
  • --->
  • <cfset qCredit = QueryNew(
  • <!--- Column names. --->
  • strColumns.ReplaceAll( "\s*::[^,]+", "" ).ReplaceAll( ",\s*", ", " ).Trim(),
  •  
  • <!--- Column types. --->
  • strColumns.ReplaceAll( ",[^:]+::\s*", ", " ).ReplaceAll( "^[^:]+::\s*", "" ).Trim()
  • ) />

As you can see, I am creating a mapping between the column names and the column data types that is quite easy to read and maintain. Then, for the actually QueryNew() method call, I am just stripping out the unwanted characters for each QueryNew() argument. Sure, this might not be the fastest method, but I think it will be the best method (for me) for large queries over time. After all, this is the alternative:

 Launch code in new window » Download code as text file »

  • <cfset qCredit = QueryNew(
  • "data, rfid, date, time, gross, tare, net, level, rolloverid, rb_dollars, is_valid, is_invalid_account, is_invalid_entry, is_invalid_tare, is_duplicate_credit, useraccount_id, rfid_count, address_id, street1, street2, city, state, zip",
  • "VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, DECIMAL, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR, VARCHAR"
  • ) />

Try telling me what the heck is going on there without counting on your fingers!

The only issue I have is that it requires a bit more code. What would be cool is to be able to make that in to a custom tag; something like:

 Launch code in new window » Download code as text file »

  • <sys:querynew name="qCredit">
  • data :: VARCHAR,
  • rfid :: VARCHAR,
  • date :: VARCHAR,
  • time :: VARCHAR,
  • gross :: VARCHAR,
  • tare :: VARCHAR,
  • net :: VARCHAR,
  • level :: VARCHAR,
  • rollover_id :: VARCHAR,
  • rb_dollars :: DECIMAL,
  • is_valid :: INTEGER,
  • is_invalid_account :: INTEGER,
  • is_invalid_entry :: INTEGER,
  • is_invalid_gross :: INTEGER,
  • is_invalid_tare :: INTEGER,
  • is_invalid_net :: INTEGER,
  • is_duplicate_credit :: INTEGER,
  • useraccount_id :: VARCHAR,
  • rfid_count :: VARCHAR,
  • address_id :: VARCHAR,
  • street1 :: VARCHAR,
  • street2 :: VARCHAR,
  • city :: VARCHAR,
  • state :: VARCHAR,
  • zip :: VARCHAR
  • </sys:querynew>

That sort of tag would take about 3 seconds to implement and would be quite useful (it would return the qCredit query if that was not clear). I am not a FuseBox guy, but this might be something like what QuerySim tried to do. The difference is that I am not creating records, I am creating record SETS. Anyway, I was quite happy with this solution, thought I would pass it on.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Dec 4, 2006 at 4:12 PM // reply »
1 Comments

"The difference is that I am not creating records, I am creating record SETS."

In the context of queries, records == record sets. I think what you mean to say is:

"...I am not creating record sets, I'm defining record sets."


Dec 4, 2006 at 4:19 PM // reply »
6,516 Comments

Paul,

Yes, excellent distinction. I am just defining the record set. Thanks for correcting that. I was trying to emphasize that this has nothing to do with adding records (but both methods actually created record sets).


Dec 5, 2006 at 4:26 AM // reply »
15 Comments

Why include the commas in your custom tag, when newline is a perfectly good delimiter, and means you can't suffer from the annoying "oh crap, I missed the last comma /again/" thing.


Dec 5, 2006 at 7:13 AM // reply »
6,516 Comments

Excellent point. There is no real need for the comma. I think I just had it in because I was thinking about stripping away characters. Without the comma in the original data, I would need to add it in during the ReplaceAll()s, which would not be complicated.


Apr 2, 2008 at 10:39 AM // reply »
1 Comments

I am using querynew() to create a query on the fly..
Getting errors in Production environment that i did not get in DEV..
I am suspecting it has to do with the versions of Coldfusion we have installed on the different environment..

In DEV i get no error..

In PROD...i am getting slammed by:
***************************************************
Parameter validation error for function QUERYNEW. The function takes 1 parameter.
The error occurred on line 86.
***************************************************

My question is, is there a difference in the versions..? 6 vs 7 or 7.0.2?

Thanks.


May 13, 2008 at 8:27 AM // reply »
6,516 Comments

@Victor,

Yeah, QueryNew() starts taking more parameters in the new versions. Specifically, I think the data type column options.

I know you probably already know this, but you should probably have the same version of ColdFusion in your dev and your production environments :P sorry, that's just the teacher in my coming out.


Nov 1, 2009 at 12:54 PM // reply »
42 Comments

When my xmlquery gets to be 800 rows or more it takes a long time to load, if it gets to 1600 rows it times out (20 seconds). Much slower then pulling from database. any performance tips for querynew. or other alternatives. I'm probably doing something wrong ?


Nov 1, 2009 at 1:53 PM // reply »
42 Comments

Its seems to me that it is faster to do a cffile read and only loop throught part of the dataset, using find() or something like to filter. I can read and find stuff in a secound, with basic find() and cffile. But when i use querynew it always takes 20 secs or timeout with larger datasets. It all depends how much you are outputting with cffile on the speed. I only want to display 12 files at a time so this works much better. If I wanted to display all the results on one page it would be same speed.


Nov 1, 2009 at 2:43 PM // reply »
6,516 Comments

@James,

What kind of data are you storing? May I ask why you are using a file rather than a database?


Nov 2, 2009 at 5:18 PM // reply »
42 Comments

@ Ben
I am trying to max out my gdidy account. They only offer up to 200 simultaneous mysql transactions. But unlimited data transfer, and storage.

So i am trying to leverage what really needs database access (which is easier, faster etc) and what I can store in xml for access. And what I can make static. And a bit of normalizing. I liked how the query new object worked but its Slow !. really really really slow. But very convenient, since its so similar. But it takes 20 secounds to pull what the database takes in 2-3 secs. So its cant be an option unless I can make it faster.

But for the most part im storing text. For which to be searched.

My questions might sound nutz , im not formally trained.


Nov 3, 2009 at 12:28 PM // reply »
6,516 Comments

@James,

Have you considering serializing the query into XML via WDDX and then saving that file. That way, you can de-serialize the WDDX file back into a query - it might be faster?


Nov 3, 2009 at 6:28 PM // reply »
42 Comments

No - but I will now, just got to figure it out, never used WDDX method before.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 6:47 PM
Hal Helms - Real World Object Oriented Development, Sarasota - Day Five
@charlie griefer, Thank you.. ... read »
Nov 21, 2009 at 5:15 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jose Galdamez, Oh heh yeah I didn't paste the whole code. I should have defined the vars -- my bad. It's fixed thou. Thanks. ... read »
Nov 21, 2009 at 4:49 PM
Styling The ColdFusion 8 WriteToBrowser CFImage Output
Great work yet again Ben! Whilst I didn't use this whole code, I copied some of your regex code for a similar problem with the lack of an alt attribute and unescaped ampersands in CFIMAGE for Railo 3 ... read »
Nov 21, 2009 at 1:13 PM
My First ColdFusion Builder Extension - Encrypting And Decrypting CFM / CFC Files
@Ben, Because I am pedantic, I just want to make sure that everyone knows there is absolutely no encryption going on. There is only encoding and obfuscation. The cfencode tool only obfuscates your C ... read »
Nov 21, 2009 at 12:28 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jody I can't seem to get your code sample to work. If you are still having problems, try this code out and see if it gets you what you wanted. <!--- Comma delimited list with various duplicates ... read »
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »