Using cfqueryparam With An 'IN' Clause

Posted By : todd sharp Posted At : February 13, 2007 3:29 PM Posted In: SQL, ColdFusion

15

I was just working on a query that was acting up a bit and thanks to the ever brilliant Raymond Camden who bailed me out in about 2 seconds with the solution. I figured I ought to blog the issue for those who may come across this.

Essentially I needed to pass a potential list of values into my query as an 'in' list. My function looked something like this (disclaimer: this is sql server syntax - your db may be different)

<cffunction name="myFunc">
<cfargument name="list">
<cfset var inList = listQualify(arguments.list, "'")>
<cfset var myQ = "">
<cfquery name="myQ" datasource="bravo">
select alpha
from charlie
where whiskey in <cfqueryparam value="(#preserveSingleQuotes(inList)#)">
</cfquery>
<cfreturn myQ />
</cffunction>

My first issue was the parenthesis within the value of the cfqueryparam. Ray quickly noted that it should be something like this:

where whiskey in (<cfqueryparam value="#inList#" list="true">)

Note the parenthesis outside of the cfqueryparam and the addition of the list="true" attribute and the removal of preserveSingleQuotes. However this still wasn't working for me. The fix was simple however - it seems that the list attribute automatically qualifies the list for you - so the listQualify was not necessary. The end result - which worked perfectly - looked something like this:

<cffunction name="myFunc">
<cfargument name="list">
<cfset var myQ = "">
<cfquery name="myQ" datasource="bravo">
select alpha
from charlie
where whiskey in (<cfqueryparam value="#arguments.list#" list="true">)
</cfquery>
<cfreturn myQ />
</cffunction>

Comments (15)

Ben Nadel's Gravatar Yeah, the List attribute is pretty sweet! One of the things that I love about it is that it ignores empty values:

"#arguments.list#,,,,0,,,,,0,,,"

will not error out. It ignores the empty commas. This means that you can put things like this:

"#arguments.list#,0"

if you are not sure if the list will have a length. If it does, then zero is usually ignored (when working with IDs and what not). If it does not have a length, then it comes out to be ",0" which CF just treats as "0".

Sweet!

Dave's Gravatar Thanks. I as just struggling with this. If you have time might be
worth adding to the coldfusion cookbook.
http://www.coldfusioncookbook.com/

Adam Ness's Gravatar Another Gotcha:

If arguments.list is an empty list (i.e. arguments.list eq "") then this SQL statement will error out. You should always check anything that's going into an <cfqueryparam list="yes"> tag, to make sure it's not blank.

John's Gravatar You jus saved my life of qualifying a very long list of unique-identifiers every time to use in similar query.

I just used this provided line with the list of GUIDs without qualifying each one of them, and it worked fine.

Thanks again!

todd sharp's Gravatar Awesome! Glad I could help John.

Al's Gravatar Awesome, this is just what I was looking for after banging my head against the wall for quite some time. Should've been obvious to use the list attribute but oh well.

Glad you posted about this!

David Levin's Gravatar Note: there is a limitation to using IN clauses with MSSQL. Once you reach a list length of a couple thousand records you will get an error. See this link from Microsoft:
http://support.microsoft.com/kb/288095

Joel's Gravatar Awesome, thanks! This cured an error I was getting for an empty list.

victor's Gravatar How would you treat this with cfqueryparam?
is this the proper syntax?
<cfquery name="myQ" datasource="bravo">
select alpha
from charlie
where whiskey in <cfqueryparam value="(#ListQualify(form.Genus, "'")#)">

victor's Gravatar Just realized this is an old post, but much to the subject...
answering my own question, the proper form would be this:

where Genus in (<cfqueryparam value="#form.Genus#" list="yes" separator="'">)

prims07's Gravatar Is there any way to accomplish the same in MySQL. I am trying to create a stored procedure from query that I had. Thanks in advance.

todd sharp's Gravatar @prims07 this would work just the same with MySQL. If you're using a stored procedure the only change would be to use cfprocparam instead of cfqueryparam

Matt's Gravatar I might be proven wrong but I'm pretty sure that this will not work with cfprocparam as it does not have a list attribute.

prims07's Gravatar So is there any other way to do the same using Stored procedure? I took long approach and did using prepared statement (which to this day I didn't like). Thanks again

Adi's Gravatar Great Help.
Thanks