在ColdFusion中,属性值周围的单引号和双引号有什么作用?

时间:2012-06-26 22:59:11

标签: sql coldfusion cfqueryparam

例如,围绕#Trim(FORM.fromfirstname)#做什么?我正在添加<cfqueryparam...>个标签,我想知道是否还需要引号?

<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>

这是一个不使用WHERE子句的引号:

<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>
编辑:如果他们不做任何事情,保留他们没有坏处,对吗?在另一个文件中,我找到了像

这样的例子
    to="#ListFirst(EnglishEmailList)#"
    cc="#ListRest(EnglishEmailList)#"

所以,如果他们已经在那里,我会离开他们吗?

4 个答案:

答案 0 :(得分:10)

SQL需要字符串引用。

引号是标准SQL语法的一部分,用于表示字符串(实际上它们几乎适用于所有语言)。

如果它没有引号,那么SQL解析器就不知道字符串的结束位置和SQL的继续。

数字不需要引号 - 价值结束的地方没有歧义。

还要记住#hashes#与SQL无关 - 它们完全在CFML方面。运行cfquery标记时,CF会评估正文(包括它包含的任何哈希表达式)以创建SQL字符串,然后将其传递给数据库(以及其他设置/参数/等)。 SQL服务器不知道该字符串的哪些部分是硬编码的,哪些部分可能是从哈希值中评估的。


cfqueryparam不需要引号。

当您修复查询以使用cfqueryparam时,您正在创建参数,并且标记处理指示SQL数据库的字符串/ etc所需的所有内容。 (您永远不需要将cfqueryparam标记本身包含在引号中。)

在cfqueryparam标签中,无论你是否使用属性的引号,它都是零差异 - 这三个都产生相同的结果:

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

答案 1 :(得分:5)

如果您使用的是<cfqueryparam>,那么您永远不需要使用引号。

如果您在SQL中比较字符串(而不是使用<cfqueryparam>),则需要使用引号。如果您要与某个数字进行比较(而不是使用<cfqueryparam>),那么您就不需要引号。

答案 2 :(得分:3)

如果您没有使用queryparam标记,那么字符串仍然需要引号,并且只要有可能就应该在查询中使用queryparams。

不使用该功能会为SQL注入创建一个可能的攻击点,几乎是滥用的邀请。

答案 3 :(得分:2)

我知道这很乏味,但是如果你在将变量插入SQL语句之前清理它们,那么它就更容易理解和阅读。

以下是我写这个的方法:

// 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>

在以下SQL语句的WHERE子句中,您输出的是一个整数,因此不需要引号。

    WHERE user_id = #getUser.user_id#

当然,搞砸数据库很容易。使用cfqueryparam并保存你的工作......

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

不要在SQL语句中进行IF / ELSE登录,而是先执行此操作,如下所示:

<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#