【问题标题】:Is this a ColdFusion Bug in cfscript?这是 cfscript 中的 ColdFusion 错误吗?
【发布时间】:2013-01-18 22:34:51
【问题描述】:

这是一个有效的查询,用于返回用户表中用单引号括起来的电子邮件。

SELECT  '''' +email + '''' as email
FROM    users
where fname = @fname

然而,当我尝试在这样的 cfscript (cf9) 查询中执行此操作时:

var q = new Query(datasource="warewithal");
q.setSQL("SELECT  '''' +email + '''' as email
                FROM users where firstName= :firstName ");
q.addParam(name="firstName", value=trim(firstName), cfsqltype="cf_sql_varchar");

我最终得到的是

Email
+email+

当我期望的时候(并通过在分析器中运行查询得到)

Email
'bozo@clowns.com'

cfscript 正在执行 perserveSingleQuote 并且不允许我将单引号添加到输出中。

这是一个错误还是我做错了什么?

【问题讨论】:

  • 你试过用两个单引号而不是 4 个吗? 3、5 或 6 个怎么样?
  • 您使用的是什么数据库类型? (将其包含在查询相关问题的标签中总是好的)。
  • (编辑)虽然它肯定与在Query.cfc 中使用preserveSingleQuotes 有关,但我在SQL Server 上测试您的代码时得到了不同的结果(数据库语法错误)。因此,尚不清楚它是否是一个错误 - 或者是否是 - 是否严格来说是一个 CF 错误。不知道为什么需要这样做,但作为一种解决方法,您可以使用 CF 代码(更典型)将其添加到表示层中,或者可能使用数据库的字符串函数来生成单引号。即在 SQL Server 中:SELECT char(39) + email + char(39) AS Email ...
  • 我试图理解为什么您需要将结果用单引号括起来。当您需要输出时,在电子邮件地址周围加上单引号可能更容易,不是吗?
  • 你也可以尝试使用你的 DBMS 内置的连接函数,比如 SQL server 中的 concat()

标签: coldfusion coldfusion-9 coldfusion-10


【解决方案1】:

回答标题中的问题:不,这不是 CFScript 中的错误。您所展示的内容与 CFScript 完全无关。

但是回答你意思要问的问题:是的,你在 Query.cfc 中发现了一个错误。

这是一些演示该错误的代码(并证明它与 CFScript 无关,而与 Query.cfc 无关)。

这段代码运行良好:

<cfset query = new Query(datasource="scratch_mssql")>
<cfset query.setSql("
    SELECT  '''' + email + '''' as email
    FROM    users
    WHERE   firstName = '#firstName#'   
")>
<cfset emailAddresses = query.execute().getResult()> 
<cfdump var="#emailAddresses#">

请注意,我已将过滤器值硬编码到 SQL 字符串中。呸。

此代码错误:

<cfset query = new Query(datasource="scratch_mssql")>
<cfset query.setSql("
    SELECT  '''' + email + '''' as email
    FROM    users
    WHERE   firstName = :firstname  
")>
<cfset query.addParam(name="firstname", value=firstName, cfsqltype="CF_SQL_VARCHAR")>
<cfset emailAddresses = query.execute().getResult()> 
<cfdump var="#emailAddresses#">

我的错误是:

[Macromedia][SQLServer JDBC Driver][SQLServer]An object or column name is missing or empty.For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.

仅供参考:CF 传递给数据库的 SQL 是:

SELECT  '' '' + email + '' '' as email FROM users WHERE firstName = (param 1)

为了证明它是由 ColdFusion 错误处理您的单引号引起的,这是可行的:

<cfset query = new Query(datasource="scratch_mssql")>
<cfset query.setSql("
    SELECT  email as email
    FROM    users
    WHERE   firstName = :firstname  
")>
<cfset query.addParam(name="firstname", value=firstName, cfsqltype="CF_SQL_VARCHAR")>
<cfset emailAddresses = query.execute().getResult()> 
<cfdump var="#emailAddresses#">

如果我是你,我会为此提出bug。注意:在CF9.0.2和CF10.0.7上是一样的

但是,同样...如果我是你,无论如何我都不会把那些引号放在那里。除非有很好的理由,否则请在显示时将它们插入,而不是在进行数据处理时插入。我想它们是为了展示目的?

【讨论】:

  • 亚当,错误示例中生成的 SQL 是什么?
  • 我想知道这是否与你们在 2010 年搞砸的这篇文章有关,哈哈。 forums.adobe.com/message/2986794
  • @Travis - 很好的发现。我在调试它时发现了同样的事情.. 只晚了几个小时;) CF10 的Query.cfc 似乎包含一个类似的includeEmptyFields=true 修复。不幸的是,循环逻辑还在双引号之间增加了一个额外的空格。这就是导致我前面提到的 sql server 语法错误的原因。删除空间,它工作正常。
  • @Travis:我已经更新了文本以包含 SQL。在 CF9 + 10 上都是一样的。
  • 只是一个观察:railo 4.0.2 也有这个问题,这个代码。
【解决方案2】:

对于它的价值,我只是被这个问题所吸引。似乎有效的是对 Query.cfc 对象 (/[YOUR-CF-INSTALL]/CustomTags/com/adobe/coldfusion/Query.cfc) 的简单修复。在 replaceDelimsWithMarkers() 函数中,更新这一行(对我来说是 LN 341)

newSql = newSql & SINGLEQUOTE & sqlArray[i] & SINGLEQUOTE & " ";

通过删除末尾的引号空格,它是:

newSql = newSql & SINGLEQUOTE & sqlArray[i] & SINGLEQUOTE & "";

然后效果很好。我正在查找用户,需要找到姓氏为“O'Neill”的用户。无论我做什么,我都会得到“O''Neill”,正如你所说的那样失败了。

您能想到这种更改/修复会产生负面影响的任何情况吗?我不能离开我的头顶,但现在我们要复制 query.cfc 文件,重命名它并将其用作自定义标签,仅当我们需要运行我们怀疑可能使用额外撇号的查询时。唯一的区别就是这一点小变化。

【讨论】:

    猜你喜欢
    • 2013-05-08
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多