سؤال

For example what do the "" around #Trim(FORM.fromfirstname)# do? I'm adding <cfqueryparam...> tags and am wondering if the quotes are still required?

<CFQUERY NAME="account" DATASOURCE="#APPLICATION.centralDSN#">
    SELECT * 
    FROM users
    WHERE (firstname =<CFQUERYPARAM VALUE="#Trim(FORM.fromfirstname)#">)
        AND (lastname = <CFQUERYPARAM VALUE="#Trim(FORM.fromlastname)#">)
        AND (email = '#Trim(FORM.fromemail)#')
</CFQUERY>

Here's one that doesn't use quotes for the WHERE clause:

<CFIF getUser.RecordCount>
    <CFQUERY NAME="cUser" DATASOURCE="#APPLICATION.centralDSN#">
        UPDATE users
            SET mailing_list = <CFIF IsDefined("FORM.mailing_list")>#FORM.mailing_list#<CFELSE>0</CFIF>
        WHERE user_id = #getUser.user_id#
    </CFQUERY>
</cfif>

EDIT: if they don't do anything there's no harm in keeping them, correct? In another file I found examples like

    to="#ListFirst(EnglishEmailList)#"
    cc="#ListRest(EnglishEmailList)#"

So if they are already there I'll leave them?

هل كانت مفيدة؟

المحلول

SQL needs quotes for strings.

Quotes are part of standard SQL syntax to indicate a string (as indeed they are in almost every language).

If it didn't have quotes then SQL parser would have no idea where the string ended and the SQL continued.

Quotes are not necessary for numbers - where there is no ambiguity about where the value ends.

Remember also that the #hashes# are nothing to do with SQL - they are entirely on the CFML side. When running the cfquery tag, CF evaluates the body (including any hash expressions it contains) to create an SQL string, which is then passed to the database, (along with additional settings/parameters/etc). The SQL server has no knowledge of what parts of that string was hard-coded and what parts might have been evaluated from hashes.


cfqueryparam doesn't need quotes.

When you're fixing the queries to use cfqueryparam, you are creating parameters, and the tag handles everything necessary to indicate strings/etc to the SQL database. (You never need to wrap the cfqueryparam tag itself in quotes.)

Within the cfqueryparam tag, it makes zero difference whether or not you use quotes for the attributes - these three all produce the same result:

<cfqueryparam value="#var#" />
<cfqueryparam value='#var#' />
<cfqueryparam value=#var# />

نصائح أخرى

If you're using <cfqueryparam> then you never need to use quotes.

if you're comparing a string in SQL (and not using <cfqueryparam>) then you need to use quotes. If you're comparing to a number (and not using <cfqueryparam>) then you don't need quotes.

The quotes are still required for strings if you're not using a queryparam tag and you should use queryparams for any variables in queries whenever it's possible.

Not using that feature would create a possible attack point for SQL injection and is almost an invitation for abuse.

I know it's tedious, but if you clean up your variables BEFORE you insert them into an SQL statement it's easier to understand and read.

Here's how I would write this:

// manipulate and rescope variables as required here
// no quotes or pound signs necessary when when not outputting
<cfset VARIABLES.FirstName = Trim(FORM.fromfirstname)>
<cfset VARIABLES.LastName  = Trim(FORM.fromlastname)>
<cfset VARIABLES.Email     = Trim(FORM.fromemail)>

// stop sql inject ~ use cfqueryparam
// simplifying your sql statement will make it much easier to diagnose problems
<CFQUERY NAME="account" DATASOURCE="#APPLICATION.centralDSN#">
    SELECT * 
    FROM users
    WHERE  firstname = <CFQUERYPARAM cfqltype='cf_sql_varchar' VALUE="#VARIABLES.FirstName#"> 
        AND lastname = <CFQUERYPARAM cfqltype='cf_sql_varchar' VALUE="#VARIABLES.LastName#">
        AND email    = <CFQUERYPARAM cfqltype='cf_sql_varchar' VALUE="#VARIABLES.Email#">
</CFQUERY>

In the following SQL statement's WHERE clause, you are outputting an integer, so no quotes are necessary.

    WHERE user_id = #getUser.user_id#

Of course, it would be easy to screw up your database. Use cfqueryparam and save your job...

    WHERE user_id = <CFQUERYPARAM  cfqltype='cf_sql_integer'  VALUE="#VARIABLES.user_id#">

Instead of doing your IF/ELSE login inside your SQL statement, do it before, like this:

<cfif isDefined("FORM.mailing_list")>
  <cfset VARIABLES.mailing_list = trim(FORM.mailing_list)>
<cfelse>
  <cfset VARIABLES.mailing_list = 0>
</cfif>

UPDATE users
SET mailing_list = <cfqueryparam cfsqltype="cf_sql_varchar" value="#VARIABLES.mailing_list#">
WHERE user_id = #getUser.user_id#
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top