4

例如,#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

4 回答 4

11

SQL 需要字符串的引号。

引号是标准 SQL 语法的一部分,用于指示字符串(实际上几乎每种语言都有引号)。

如果它没有引号,那么 SQL 解析器将不知道字符串在哪里结束并且 SQL 继续。

数字不需要引号 - 值的结束位置没有歧义。

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


cfqueryparam 不需要引号。

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

在 cfqueryparam 标记中,无论您是否为属性使用引号,都将产生零差异——这三个都产生相同的结果:

<cfqueryparam value="#var#" />
<cfqueryparam value='#var#' />
<cfqueryparam value=#var# />
于 2012-06-26T23:47:53.447 回答
5

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

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

于 2012-06-26T23:10:14.707 回答
3

如果您不使用 queryparam 标记,则字符串仍然需要引号,并且您应该尽可能对查询中的任何变量使用 queryparams。

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

于 2012-06-26T23:19:43.547 回答
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#
于 2012-06-26T23:53:21.900 回答