Cannot Use ColdFusion CFQueryParam With SQL TOP Directive

Posted January 10, 2007 at 12:36 PM by Ben Nadel

Tags: ColdFusion, SQL

I just came across a strange little error that took me a few minutes to debug. I was running this SQL query:

  • DELETE FROM
  • reward
  • WHERE
  • order_id = 0
  • AND
  • delivery_id = <cfqueryparam value="#id#" cfsqltype="CF_SQL_INTEGER" />
  • AND
  • id IN
  • (
  • SELECT TOP <cfqueryparam value="#(qUnused.reward_count - FORM.quantity)#" cfsqltype="CF_SQL_INTEGER" />
  • id
  • FROM
  • reward
  • WHERE
  • order_id = 0
  • AND
  • delivery_id = <cfqueryparam value="#id#" cfsqltype="CF_SQL_INTEGER" />
  • ORDER BY
  • id DESC
  • )

... and it was throwing this error:

[Macromedia][SQLServer JDBC Driver][SQLServer]
Line 11: Incorrect syntax near '@P2'.

Looking at the debugging SQL:

  • DELETE FROM
  • reward
  • WHERE
  • order_id = 0
  • AND
  • delivery_id = (param 1)
  • AND
  • id IN
  • (
  • SELECT TOP (param 2)
  • id
  • FROM
  • reward
  • WHERE
  • order_id = 0
  • AND
  • delivery_id = (param 3)
  • ORDER BY
  • id DESC
  • )

... I can see that Param 2 is the SQL TOP value. Going in and take the CFQueryParam out and replace it with:

  • SELECT TOP #(qUnused.reward_count - FORM.quantity)#

... things work just fine. Apparently, you cannot use the CFQueryParam with the SQL TOP statement. Not sure what this is all about. It seems like this is a place where SQL injection could occur (especially in my case where the TOP value is being derived from a FORM value). Perhaps this is just not the best way for me to accomplish this goal.



Reader Comments

Jan 10, 2007 at 1:28 PM // reply »
15 Comments

There was a bug in recent updates to CF that caused using Maxrows on a query to be problematic. I went changing some old queries that used the maxrows to use top instead and came across this as well. I don't think this is a CF but rather a MS SQL issue.


Jan 10, 2007 at 1:29 PM // reply »
15 Comments

There was a bug in recent updates to CF that caused using Maxrows on a query to be problematic. I went changing some old queries that used the maxrows to use top instead and came across this as well. I don't think this is a CF but rather a MS SQL issue.


Jan 10, 2007 at 1:31 PM // reply »
15 Comments

Sorry my comment got posted twice, but FYI I got a 500 null error when I submitted it both times and didn't think it went through...also I checked remember my information and it does not seem to have done so. Just letting you know.


Jan 10, 2007 at 2:33 PM // reply »
11,246 Comments

Thanks for letting me know. Something has gone a bit cookey with the comment posting in the last few days. I have to figure out what happened. I am on it!


Jan 10, 2007 at 2:48 PM // reply »
11,246 Comments

Ok I made an update to the comment. Please let me know if anything goes wrong again.

Thanks!


Jan 10, 2007 at 2:49 PM // reply »
48 Comments

How about this Ben? Before the query do:

declare @param int
set @param = <cfqueryparam value="#id#" cfsqltype="CF_SQL_INTEGER" />

then in your query do a:

select top @param......

not tested, but should work....


Jan 10, 2007 at 2:50 PM // reply »
48 Comments

OK i lied - maybe it doesn't work...


Jan 10, 2007 at 2:53 PM // reply »
11,246 Comments

Todd,

Nice thought. I guess it just can't handle binding in general? As Brian says above, at least it's not a ColdFusion error, but one of the SQL server.


Jan 10, 2007 at 3:00 PM // reply »
48 Comments

If it's that important, you could always make the sql dynamic like this:

DECLARE @param int
set @param = <cfqueryparam value="#id#" cfsqltype="CF_SQL_INTEGER" />

DECLARE @sql nvarchar(4000)
SELECT @sql = ' SELECT top ' + @param + 'columns and stuff'+
' FROM ...' +
' WHERE...'

EXEC sp_executesql @sql


Jan 10, 2007 at 3:01 PM // reply »
48 Comments

That one WAS tested ;)


Jan 10, 2007 at 3:06 PM // reply »
15 Comments

In general, unless it is completely necessary, I avoid dynamic sql like that. The reason is that it is my understanding that when using dynamic sql like that MS SQL recompiles the execution plan on every request - so it would negate the performance benefit of using the queryparam to create a prepared statement I believe. This would also be the case even if your dynamic SQL was in a stored procedure...execution plan is recreated on each call...


Jan 10, 2007 at 3:08 PM // reply »
11,246 Comments

Todd,

Sorry, that goes way beyond my understanding. I mean, I get what you are doing, but I know zero about dynamic SQL execution :)


Jan 10, 2007 at 3:19 PM // reply »
48 Comments

What about this Brian/Ben?

<cfquery...>
set rowcount <cfqueryparam value="1" cfsqltype="cf_sql_integer">
select *
from tbl...
where stuff...
set rowcount 0
</cfquery>

Would this cache the execution plan? It solves the TOP n issue, and it works...


Jan 10, 2007 at 3:21 PM // reply »
48 Comments

Though I would be nervous doing that with a delete...


Jan 10, 2007 at 3:22 PM // reply »
48 Comments

sorry for being a comment wh*re...


Jan 10, 2007 at 4:49 PM // reply »
171 Comments

I would imagine the reason it doesn't work is you can't bind a variable to the TOP directive.

Why not just use:

SELECT TOP #val(qUnused.reward_count - val(trim(FORM.quantity)))#

This should prevent SQL Injections and the val() function will make sure your value is seen as an integer.


Jan 10, 2007 at 5:04 PM // reply »
11,246 Comments

@Todd,

No worries on being a wh*re ;) Comments rock. Thinking out-loud rocks.

@Dan,

Nice tip on Val().

Good stuff all around.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 24, 2013 at 5:39 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam Oops! My mistake! I hadn't gotten that far in my testing - I'm still baby stepping my way through the process. ... read »
May 24, 2013 at 5:13 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
Hi Jason, Thanks for checking up on that, but I still stand firm on my position. :) There are actually two listLast()'s in use, and you're right that the one using a space as a delimiter is fine. ... read »
May 24, 2013 at 4:45 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Ben I have been lurking your site for quite some time, and haven't stepped up to comment until today. Thanks for all the great info - keep it up! @Adam I believe you are mistaken... as the commen ... read »
May 24, 2013 at 11:21 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, Ha ha, let's us never speak of justifying "##" notation again :P ... read »
May 24, 2013 at 11:18 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Ah, so it was indeed how I vaguely remembered it to be: A direct assignment value = users.id[ i ] causes value to retain the sticky datatype of the query column. Although unnecessary in ... read »
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools