tracker issue : CF-3732993

select a category, or use search below
(searches all categories and all time range)
Title:

Separate parameters from SQL in <cfquery>

| View in Tracker

Status/Resolution/Reason: To Fix//

Reporter/Name(from Bugbase): Adam Cameron / Adam Cameron (Adam Cameron)

Created: 03/30/2014

Components: Language

Versions: 11.0

Failure Type: Enhancement Request

Found In Build/Fixed In Build: PublicBeta /

Priority/Frequency: Trivial / Unknown

Locale/System: English / Platforms All

Vote Count: 13

Extracted from http://cfmlblog.adamcameron.me/2014/03/querycfc-queryexecute-have-good-feature.html:
{quote}
Along comes ColdFusion 11 and we finally get the solution we should have had from the outset: queryExecute():

coloursViaQueryExecute = queryExecute("
    SELECT  en AS english, mi AS maori
    FROM    colours
    WHERE   id BETWEEN :low AND :high
    ",
    {low=URL.low, high=URL.high},
    {datasource="scratch_mssql"}
);


One function call. three arguments. Not bad.

So we can just close the chapter of ColdFusion's history that is Query.cfc, and move on.

However in all of this, we've actually picked up a feature in the function-based solutions that <cfquery> itself doesn't have. One no longer needs to have a specific piece of functionality to pass a parameter (ie: there is no equivalent of <cfqueryparam> in these functions). One can simply put a placeholder in the SQL string. the placeholder can either be a named label as per these examples, or simply a ? for positional parameters (pass an array instead of a struct in this case).

I think this is a much nicer approach to passing parameters: it completely decouples the parameter value from the SQL string, which is how it should be. The whole idea of parameters is that they are passed separately to the SQL string. The SQL string is the instructions; the parameters are the values. The values should not be hard-coded in the instructions. That's just bad programming.

So what I would like to have back-ported into <cfquery> is this:

<cfset params = {
    low     = URL.low,
    high    = URL.high
}>
<cfquery name="colours" datasource="mssql_scratch" parameters="#params#">
    SELECT  en AS english, mi AS maori
    FROM    colours
    WHERE   id BETWEEN :low AND :high
</cfquery>


Or for positional parameters:

<cfset params = [URL.low, URL.high]>
<cfquery name="colours" datasource="mssql_scratch" parameters="#params#">
    SELECT  en AS english, mi AS maori
    FROM    colours
    WHERE   id BETWEEN ? AND ?
</cfquery>


The conceit here being that parameters are passed separately to the SQL, via a parameters attribute: same as with queryExecute().

I think this approach makes the <cfquery> statement much clearer, and closer to an SQL statement's intent.
{quote}

-- 
Adam

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	3732993

External Customer Info:
External Company:  
External Customer Name: Adam Cameron.
External Customer Email:  
External Test Config: My Hardware and Environment details:

Attachments:

Comments:

Please note that Railo have already implemented this. If you implement it too, pls do it the same way: https://issues.jboss.org/browse/RAILO-2203 -- Adam
Comment by External U.
12947 | March 30, 2014 05:58:20 AM GMT
+1 Great idea.....................................
Vote by External U.
12960 | March 30, 2014 10:42:27 AM GMT
I think this a great idea, and can lead to some really clean code.
Vote by External U.
12961 | March 30, 2014 11:50:34 AM GMT
It would have perhaps been slightly more professional of you had you taken the time to communicate better about your decision here, given I'd taken the time to raise and detail the ticket for you. -- Adam
Comment by External U.
12948 | April 05, 2014 04:28:05 AM GMT
Nice Suggestion Adam! I like the proposed syntax and would be a nice addition. However, it is too late for this release. Deferring it.
Comment by Rupesh K.
12949 | April 05, 2014 10:53:16 AM GMT
Okey doke, thanks mate. -- Adam
Comment by External U.
12950 | April 05, 2014 11:01:08 AM GMT
I definitely support this. It also gives a clean way to update some legacy code that may not have query parameters.
Vote by External U.
12962 | December 05, 2014 11:26:15 AM GMT
Right. So now you're working on CF12. can you pls reopen this.
Comment by External U.
12951 | December 06, 2014 10:50:40 AM GMT
opened.
Comment by Rupesh K.
12952 | December 08, 2014 07:45:33 AM GMT
Good man!
Comment by External U.
12953 | December 08, 2014 08:33:11 AM GMT
Huge plus one to this. More character so I can vote. It would take 2 seconds - yes - two seconds - to edit the bug tracker to remove the minimum 25 char thing. Please give me access and I'll fix it.
Vote by External U.
12963 | December 08, 2014 09:49:20 AM GMT
This is my vote of support
Vote by External U.
12964 | December 08, 2014 10:03:22 AM GMT
Excellent idea, lends itself to cleaner code. Needs to still allow for complied queries like cfparam.
Vote by External U.
12965 | December 08, 2014 11:19:49 AM GMT
Brilliant idea!!! Reduce the effort and make the code clean.
Vote by External U.
12966 | June 12, 2015 02:07:08 AM GMT
I would love a cleaner query() syntax as long as the query() bugs are higher on the prio-list
Vote by External U.
12967 | July 02, 2015 03:58:37 PM GMT
Although we should probably use this tag limitation as a selling point to move to cfscript/queryExecute(), I agree this is the right thing to do. Make sure you document it.
Vote by External U.
12968 | July 02, 2015 05:52:46 PM GMT
Eh, I'm all for improving the language (and I agree that this would be an improvement), but I think this one should be low priority.
Comment by External U.
12954 | September 30, 2015 12:57:33 PM GMT
+1 ......................
Vote by External U.
12969 | September 30, 2015 02:53:22 PM GMT
And cfsqltype could also be specified? Named: <cfset params = {low = {value=URL.low, cfsqltype="CF_SQL_xxxx"}, high = {value=URL.high, cfsqltype="CF_SQL_xxxx"}}> Positional: <cfset params = [{value=URL.low, cfsqltype="CF_SQL_xxxx"}, {value=URL.high, cfsqltype="CF_SQL_xxxx"}]> Thanks!, -Aaron
Comment by External U.
12955 | September 30, 2015 02:54:34 PM GMT
Regarding my last question, I'd assume the answer would be yes. Just mentioning so it's not -forgotten-. Thanks!, -Aaron
Comment by External U.
12956 | September 30, 2015 03:01:28 PM GMT
Generally, the functionality available in the the <cfquery> tag feature should be available in the QueryExecute() script feature and vice-versa.
Vote by External U.
12970 | October 27, 2015 06:04:51 PM GMT
Can you pls confirm this is implemented in CF2016?
Comment by External U.
12957 | January 25, 2016 08:27:11 AM GMT
Is this being revisited for the next version of CF?
Comment by Chris H.
12958 | August 22, 2017 07:49:43 PM GMT
Yes, it will be evaluated.
Comment by Vamseekrishna N.
12959 | August 23, 2017 03:13:13 AM GMT