[Looking for Charlie's main web site?]

Did you know about the NULL attribute of CFQUERYPARAM? I didn't, until today.

Note: This blog post is from 2007. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
When will the riches of CFML ever cease to amaze me? :-) Did you know about the NULL attribute of CFQUERYPARAM? I didn't, until today. Consider if you use CFQUERYPARAM for an insert or update and you point its VALUE attribute to a variable. Perfectly normal, right?

But what would happen if that column in the database was designed to use NULL..but the variable used in the VALUE attribute was an empty string? It would be inappropriate for the insert or update to use an empty string when it should be a NULL.

How would you solve this? Many would just use an IF test to say, in effect, "if it's null, use a null, otherwise use the variable".

But this CFQUERYPARAM NULL attribute is just for this purpose: it accepts a boolean (true/false) to indicate whether and when to use a NULL rather than the VALUE. And rather than a simple yes/no (or true/false, 1/0, on/off, etc) you would more likely use some sort of conditional expression which EVALUATES to a boolean true/false. It could test if the variable used in the VALUE is empty.

An example of when it could make sense

So if an incoming form field like form.department could be empty, you could use:

<cfqueryparam value="#form.department#" null="#form.department is ''#">

which would pass in the form.department value--UNLESS it was an empty string, in which case it would pass in a NULL.

Again, this only makes sense when it's important to be using a NULL, such as on an insert or update.

It would NOT likely make sense in a WHERE clause

That said, note that it would NOT be appropriate if this cfqueryparam was being used in a WHERE clause. In that case, the SQL syntax of a WHERE clause equality test ("=") would NOT be appropriate in most DBs if this resolved to = NULL. Instead, the syntax for most DBs is to use "is" rather than "=". To be clear, this null attribute does NOTHING to help there. In fact, you could get an error that would leave you confused if you DID try to use it with a WHERE clause and the NULL attribute was true.

One last gotcha: the variable in VALUE is evaluated regardless

One last gotcha: while the docs say that if the NULL attribute is true, then the VALUE is "ignored", that's loose wording. It means it's not PASSED to the db as the VALUE, which is true. But it does NOT mean that CF "doesn't even pay attention to the variable named".

This has caused people trouble when they assumed they could name in the VALUE attribute a variable which might NOT exist: they assume that testing for it in the NULL should take precedence. That's just NOT how it works. CF WILL try to evaluate the variable in the VALUE attribute, whether this NULL is true or false. Forewarned is forearmed.

You'll find people using various means to test for the existence (isdefined, structkeyexists, etc.), whether testing and assigning some alternative result BEFORE this line of code, or perhaps trying WITHIN this line of code (using iif, de, and other expressions).

Update as of CF2016:

As of CF2016, one can use the "safe navigation" feature which tells CF to resolve to as an empty string if a variable doesn't exist. So one could write the code above like this:

<cfqueryparam value="#form?.department#" null="#(form?.department is '')#">

The logic there is that if the form.department field does not exist, then the VALUE will literally resolve to an empty string, and then for the NULL attribute, the same empty string WILL match the test of whether it IS an emptystring--which will be true, which means the NULL will be true and CF will pass in a NULL to the database.

It can be a lot to keep straight in your head. Try some code to check things out: but again, beware that if you use this in a WHERE clause, then the NULL being correctly passed in WILL lead to a syntax error if you're passing that to a SQL comparison like = or <>. You often need alternative SQL for dealing with NULLs--and that's NOT what this NULL attribute is for. It's for controlling simply whether CF should SEND A NULL for the VALUE!

The null attribute for cfqueryparam is not new

Finally, it may be worth nothing that this NULL attribute for cfqueryparam is not new. It's been around since 4.5 according to the CFML language history file. I'd just never noticed it before. I learned about it today from a couple of folks on the great CFAUSSIE list.

Now, to be honest, the docs (CFML Reference for the tag) just don't make it as clear as it could be, I don't think (otherwise I'd like to think I'd have noticed it before). I don't see any mention of it in the Developer's Guide, for instance.

Anyway, you can read more about it in a blog entry from Michael Sharman, who I see also just happened to blog about it last month, with a lot more detail:

http://www.chapter31.com/2007/02/04/cfqueryparam-and-conditional-handling-of-nulls/

You might also want to read the comments there as well as at the CFMX 7 docs for the tag, both of which have people sharing their experiences using the tag, over time.

For more content like this from Charlie Arehart: Need more help with problems?
  • If you may prefer direct help, rather than digging around here/elsewhere or via comments, he can help via his online consulting services
  • See that page for more on how he can help a) over the web, safely and securely, b) usually very quickly, c) teaching you along the way, and d) with satisfaction guaranteed
Comments
i knew about it thanks to an old article written by the inimitable Dave Watts.

http://www.adobe.com...

towards the bottom he illustrates how to use it instead of using <cfif> statements in the SQL to test for empty strings.

great article all around, and one that to this day i still point people towards when they have <cfqueryparam> questions.
Yeah, I recently found out about the NULL attribute also. Rocked my world something sweet! The LIST attribute is another winner.
# Posted By Ben Nadel | 3/5/07 5:13 PM
I've always been aware of this, however, there's still one "gotcha" that's always irritated me. According to the docs, if you specify a null value of true, then the "value" attribute is ignored. The gotcha is that the "value" attribute's value isn't completey ignored. Take this example:

<cfqueryparam value="#someValue#" null="#not isDefined(someValue)#">

the thought being that if #someValue# is defined, use it, otherwise use null. Yet, you'll still get an error saying someValue is not defined even though null returns true.
# Posted By Devin | 3/5/07 6:58 PM
Been using it for years and in my opinion this is the easiest way:

<cfqueryparam value="#form.headline#" cfsqltype="CF_SQL_VARCHAR" maxlength="255" null="#IIF(variables.myvar EQ "", true, false)#">

no need to use DE() around the values. Don't know why though :P
Screwed up the code in my last comment:

<cfqueryparam value="#form.headline#" cfsqltype="CF_SQL_VARCHAR" maxlength="255" null="#IIF(form.headline EQ "", true, false)#">
null="#not len(myvar)#" is a big more concise and solves the same issue if you want to avoid the iif() performance issues.
# Posted By Devin | 3/5/07 8:03 PM
I have been wanting to see a NULL="AUTO" option for years
# Posted By zac spitzer | 3/5/07 8:23 PM
Ben, I'd noticed Dave's article too, and thought about mentioning it, especially if it was much older than the blog entry I'd pointed to, but since I couldn't find a date for it. I tried for several minutes to confirm that (looking in the wayback machine, etc.), but since the names of files at Adobe/MM/Allaire have changed, it just wasn't proving fruitful. And since it didn't offer more than that entry did, I decided not to mention it. Glad you have. Sounds like you're confirming that it's been around for a while. Dave deserves credit for so much that he's done over the years.

As for those pointing out where it's failing, again, I pointed to the comments in the docs and the blog entry, where others have debated this. I've not looked into it completely, but it seemed some were indicating that things had changed over time. Perhaps updaters or hotfixes have addressed this. I'll leave it to others to explore and report.

/charlie
hey charlie...

unfortunately, i don't know the exact date of Dave's article either, but i can tell you that i made reference to it in a post on easycfm.com that's dated aug 25, 2004 (http://www.easycfm.c... so it's certainly older than a blog entry made last month :)

i'd wager that it had been around for at least a couple of years before that.
link got messed up :\

http://www.easycfm.c...

also, to address those pointing out where it's failing... i'm not sure anyone is saying it's failing, but rather taking issue with the behavior. the docs do state that a TRUE value for the null attribute will cause CF to ignore the value attribute, but that's not entirely true. it will ignore it in that it will use the NULL value (as opposed to the "value" value)... but if the "value" value does not exist, it will still try to evaluate it and throw an error.

it might have been more accurate for the docs to state that using the null attribute will OVERRIDE the value attribute, rather than stating it will ignore it.
Thanks for the clarifications, Charlie G, and all due props to Dave for his article.

Now, as for the "troublesome behavior", that's all I meant by "failing". Now, have you read all the comments in both places I pointed to, because there seemed to be some change in sentiment over time. I didn't read it closely. I'm just pointing it out for folks to consider.

And if anyone reports they do still see the "problem", can you report (for those interested) if you're running on CFMX 7.02 with the "cumulative hotfix 1"? Just seems fair to indicate if the latest and greatest version still has the issue. (Again, no, I've not read the release notes to see if they even bother to address it. Just trying to help those interested.)
The "troublesome" behavior really does exactly what it should do. It doesn't say it won't evaluate the value - it justs says it will ignore the value.

It would be weird, to me, if it conditionally didn't evaluate different parameters based on some other parameter because the evaulation takes place in one level of the processing and then the execution logic takes place in another part.
# Posted By Bill | 3/16/07 12:28 PM
HOW do you insert a NULL when the form.field is blank/has no value....? because createodbc function will throw an error with a blank input param.

<CFQUERYPARAM value="#createODBCDateTime(form.field)#"
cfsqltype="cf_sql_date" NULL="#NOT len(form.field)#>

# Posted By eric | 3/24/07 9:12 PM
Eric, look at the CFPARAM tag or the IIF function. What you're asking about is not at all unique to the CFQUERYPARAM tag's NULL attribute. I'll leave it to others to elaborate further if interested.
Hey Charlie,
Great blog post! I too wasn't pleased with the documentation provided for this attribute of <cfqueryparam>. I looked around for a better description, and instantly this page came up. Thanks for taking the time to explain this neat little feature.
I probably wouldn't have even known about it if it wasn't for CFEclipse's code hinting. When I saw it pop up I asked myself, "Does this attribute do what I think it would do?" So props to Mark Drew, et. al. as well for allowing us to learn more about CF's hidden gems.
Jose
Thanks for the kind regards, Jose, and happy to have helped. :-)
Quote

"I have been wanting to see a NULL="AUTO" option for years"

that would be amazing:

SO , in the end what the best way to do this for all types of datatypes?
# Posted By Nikos | 12/10/09 5:42 AM
There is another issue with cfqueryparam, consider the following...
set somenumber = <cfqueryparam cfsqltype="CF_SQL_SMALLINT" value="#session.number#" null="#!isNull('session.number')#" />

If session.number is blank, they it sets "null = yes" and puts in a blank value...
set somenumber = (nothing)
which will cause your query to fail.

If you change the cfqueryparam to varchar...
cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#session.number#" null="#!isNull('session.number')#" />

... then it puts empty quotes into you query
set somenumber = ''


This works great, but now I have my cfqueryparam set to varchar and it will now accept non-numeric values. Seems like a security issue to me.

I could put a conditional statement around the cfsqltype too, but damn this is getting to be a lot of extra coding to make this tag work.
# Posted By Josh | 5/7/10 3:05 PM
Thanks for sharing, Josh. Fair point. I've not dealt with it. Have you filed a bug report about that? More at http://www.carehart....
Copyright ©2025 Charlie Arehart
Carehart Logo
BlogCFC was created by Raymond Camden. This blog is running version 5.005.
(Want to validate the HTML in this page?)

Managed Hosting Services provided by
Managed Dedicated Hosting