Skip to main content
Inspiring
June 30, 2021
Answered

CFQUERY Inconsistancies?

  • June 30, 2021
  • 2 replies
  • 607 views

In the example below, assume FORM.NAME has an embedded single quote.

 

Does someone have a moment to explain why

 

<CFQUERY NAME="A" DATASOURCE="MY_LOCALHOST">
INSERT INTO TEST (NAME) VALUES ('#FORM.NAME#')
</CFQUERY>

 

works perfectly, but if I put the SQL in a variable it fails.  For example,

 

<CFSET lsSql = "INSERT INTO TEST (NAME) VALUES ('#FORM.NAME#')">

<CFQUERY NAME="A" DATASOURCE="MY_LOCALHOST">
#lsSql#
</CFQUERY>

 

fails.  Any idea why?  Or, alternatively, how could I hcvae constructed lsSql so that it would work?

 

Thanks.

ps: And using #PreserveSingleQuotes(lsSql)# didn't help.

 

    This topic has been closed for replies.
    Correct answer fredp60157821

    I found a non-eloquent work around for my problem.  I wrote some regular expressions to search for occurences of

     

    '#some variable#'

     

    and to replace all such occurences with

     

    '#DoubleUp(some variable)#'

     

    So code like

     

    <cfset p_lsSql = "INSERT INTO TEST (NAME,CITY,STREET) VALUES ('#FORM.NAME#','#FORM.CITY#','#FORM.STREET#')">

    <cfinclude template="process_sql.cfm">

     

    gets changed to

     

    <cfset p_lsSql = "INSERT INTO TEST (NAME,CITY,STREET) VALUES ('#DoubleUp(FORM.NAME)#','#DoubleUp(FORM.CITY)#','#DoubleUp(FORM.STREET)#')">

    <cfinclude template="process_sql.cfm">

     

    I had hundreds and hundreds of places to do this and without the use of regular expressions I would have had a nightmare on my hand.  With regular expressions it was trivial. For those interested my regular expressions were:

     

    Find: '#([A-Z._a-z0-9]+[A-Z._a-z0-9]*)#'

    Replace with:'#DoubleUp(\1)#'

     

    and inside template="process_sql.cfm I have

     

    <CFQUERY . . . >

    #PreserveSingleQuotes(p_lsSql )#

    </CFQUERY>

     

    I then just wrote the cutom function DoubleUp:

     

    <cffunction name="DoubleUp" output="no" access="public" returnType="string">
    <cfargument name="lsVarIn" type="string" required="true"/>
    <cfreturn Replace(lsVarIn,"'","''","ALL") />
    </cffunction>

     

    So far I haven't come across any problems with this approach and I have been able to have all my SQL pass through template. (I wanted to do this for my own reasons.)

    2 replies

    BKBK
    Community Expert
    Community Expert
    July 1, 2021

    @fredp60157821 , to specifically answer the 2 questions you raised:

    1. No, there is no inconsistency.
    2. PreserveSingleQuotes helps.

     

    You could fix your code as follows:

    <!--- Convert every ' within form.name into '' --->
    <cfset nameEscaped=replace(form.name,"'","''","all")>
    <cfset lsSql="INSERT INTO TEST (NAME) VALUES ('" & nameEscaped & "')">
    
    <CFQUERY NAME="A" DATASOURCE="MY_LOCALHOST">
       #preserveSingleQuotes(lsSql)#
    </CFQUERY>
    George____
    Inspiring
    June 30, 2021

    First a warning,  you should never do this with FORM elements, and in general should never do it.   In your example you've made it super easy for someone to perform a SQL Injection attack using FORM.NAME.    It should be within a cfqueryparam and then the single quote won't matter.

    <CFQUERY NAME="A" DATASOURCE="MY_LOCALHOST">
         INSERT INTO TEST (NAME) VALUES ( <cfqueryparam values='#FORM.NAME#'> )
    </CFQUERY>

     

    PreserveSingleQuotes is how you do this, but you have to handle the single quote in the name yourself.   So if you output #PreserveSingleQuotes(lsSql)#  you'll probably see something like this:

    INSERT INTO TEST (NAME) VALUES ('O'Niel')

    That single quote in between the O and the N needs to be doubled to be proper SQL syntax.    Couple ways you could do it, but this should work:

    <CFSET lsSql = "INSERT INTO TEST (NAME) VALUES ('" & Replace(FORM.NAME, "'", "''") & "')">
    <CFQUERY NAME="A" DATASOURCE="MY_LOCALHOST">
    #lsSql#
    </CFQUERY>

     

    Community Expert
    June 30, 2021

    Amen to @George____ for giving this warning!

     

    You might be able to avoid the quotes issue by using the CFSAVECONTENT tag.

     

    https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-r-s/cfsavecontent.html

     

    Dave Watts, Eidolon LLC

    Dave Watts, Eidolon LLC