【问题标题】:MySQL and Coldfusion date issueMySQL 和 Coldfusion 日期问题
【发布时间】:2013-01-23 19:39:20
【问题描述】:

我在 MySQL 表中有一个 timestamp 字段。我正在尝试使用以下 SQL 查询来查询表:

SELECT  login_mode,count(login_mode) as total 
FROM    login_activity,ccac_registered_users 
WHERE   login_activity.student_id=ccac_registered_users.student_id 
AND     login_date >= STR_TO_DATE('01/16/2013','%m/%d/%Y') 
AND     login_date <= STR_TO_DATE('01/17/2013','%m/%d/%Y') 
GROUP BY login_mode

当我直接在 Mysql 上运行查询时,查询工作正常,但在 Coldfusion 应用程序中无法正常工作。我难住了!生成日期的代码是:

login_date >= STR_TO_DATE(
                 '#DateFormat(CreateODBCDate(startDate),'mm/dd/yyyy')#'
                 , '%m/%d/%Y'
              )

ColdFusion 的错误是这样的:

您的 SQL 语法有错误;检查手册 对应于您的 MySQL 服务器版本,以便使用正确的语法 在 '01/16/2013'',''%m/%d/%Y'') 和 login_date

这里有什么问题?

编辑

我刚刚转储了 CF 试图执行的 sql。

SELECT login_mode,count(login_mode) as total 
FROM   login_activity,ccac_registered_users 
WHERE  login_activity.student_id=ccac_registered_users.student_id 
AND    login_date >= STR_TO_DATE(''01/16/2013'',''%m/%d/%Y'') 
AND    login_date <= STR_TO_DATE(''01/17/2013'',''%m/%d/%Y'') 

日期周围有额外的引号,它们导致了问题。如果我从代码中删除了我添加的额外内容,则不会添加任何内容。

【问题讨论】:

  • @Leigh 引用没有丢失。它位于括号的末尾。我将尝试仅使用 CreateODBCDate。 AFAIK,当我最后一次尝试时,它不能与 mysql 一起使用。
  • 哦,是的,你是对的。我的眼睛错过了一句话。
  • 您可能还想研究在查询中使用 BETWEEN。
  • 取决于所需的结果和数据本身。如果其中任何一个包含“时间”部分(很可能),那么 between 和原始查询将仅匹配 1 月 16 日午夜至 1 月 17 日午夜之间的 dated 记录。 17 日的所有其他 将被排除在外。要包含 17 日的所有时间,请使用 WHERE col &gt;= {startDateAtMidnight} AND col &lt; {dayAfterEndDateAtMidnight}

标签: mysql sql coldfusion


【解决方案1】:

(来自我之前的评论...)

绝对没有必要使用dateFormatstr_to_dateDateFormat 设计用于演示并返回一个字符串。您应该使用的是日期对象。 CreateODBCDate 已经给你了。因此,只需在查询中直接使用它。 (显然,您应该始终先验证输入)

 WHERE column >= #CreateODBCDate(startDate)#  
 ....

.. 或者更好的是,使用 cfqueryparam:

 WHERE column >= <cfqueryparam cfsqltype="cf_sql_date" value="#startDate#">

【讨论】:

    【解决方案2】:

    使用查询参数和日期对象而不是字符串。像这样:

    AND login_date >= <cfqueryparam cfsqltype="cf_sql_date" value="#CreateDate(2013,1,16)#"> 
    AND login_date <= <cfqueryparam cfsqltype="cf_sql_date" value="#CreateDate(2013,1,17)#">
    

    【讨论】:

      【解决方案3】:

      CFQUERY 喜欢自动转义单引号。要让它按照您编写的方式工作,您需要将内容包装在 preserveSingleQuotes() 中,以防止 CF 添加额外的单引号。或者使用其他日期比较建议之一重写它。

      【讨论】:

      • 我已经有一段时间没有使用 MySQL 了,但是如果你可以使用双引号将参数传递给函数,那将完全避免这个问题:STR_TO_DATE("#DateFormat(CreateODBCDate(startDate),'mm/dd/yyyy')#","%m/%d/%Y")
      • 查询是动态形成的,它已经用双引号括起来,因此使用单引号。
      • 请不要推荐使用preserveSingleQuotes而不提及它完全撤消CF添加的自动保护并将您的数据库暴露给sql注入。不要使用它,除非你知道你正在进入什么并且彻底清理了你的数据。
      【解决方案4】:

      我建议使用 DateDIff 来执行日期比较,而不是比较字符串中的日期,这对我的 4 个应用程序非常有效

      详情在这里:http://www.w3schools.com/sql/func_datediff_mysql.asp

      【讨论】:

      • 我不同意。在 where 子句中使用函数通常会使查询运行速度变慢。如果相关字段已被索引,则尤其如此。
      【解决方案5】:

      在 SQL 中使用:

          CONVERT(DateTime, DateField, 104)
      

      或尝试:

          CAST( right(@date,4) + left(@date,4) as datetime )
      

      我认为 ColdFusion 等价物是:

          <cfset date = DateFormat(date, "mm/dd/yyyy")>
      

      ——不是吗?

      【讨论】:

      • DateFormat 不适用于字符串,需要一个日期/时间对象。
      • @VaishakSuresh - 它是为 dates 设计的,是的。但与 CF 中的大多数日期函数一样,它也很容易接受“可解析”的日期字符串。请注意,它始终被解释为美国日期字符串。
      猜你喜欢
      • 2010-10-18
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 2011-07-10
      • 2012-05-02
      相关资源
      最近更新 更多