2

我有一个 HTML 表单,我要求用户选择日期,然后点击提交。提交后,我正在尝试使用 ColdFusion 获取所选日期之间的记录。我的查询如下所示:

SELECT  * 
FROM    user_activation_events
where   STATUS_CODE =1
AND     event_date >= #Dateformat(form.from_date, 'dd-mm-yyyy')#
AND     event_date <= #Dateformat(form.to_date, 'dd-mm-yyyy')#

但这不起作用,因为日期以这种格式存储在数据库中:

    yyyy-mm-dd hh:mm:ss

有人可以告诉我该怎么做吗?

4

2 回答 2

3

这里有几个问题。任何以 _date 结尾的表单字段都是表单验证条件。所以表单域需要重命名为todate和fromdate。接下来,您最好尝试清理输入。cfqueryparam习惯于这样做。最后但并非最不重要的一点是,介于两者之间的是更简洁的 SQL 您的查询应该看起来有点像:

<cfif isDate(form.fromDate) AND isDate(form.toDate)>

    <cfquery name="qryUser_Activation_Events">
    SELECT * 
    FROM   user_activation_events
    WHERE  STATUS_CODE =1
    AND    event_date BETWEEN <cfqueryparam cfsqltype="CF_SQL_date" value="#form.fromDate#">
        AND DATEADD(d, 1, <cfqueryparam cfsqltype="CF_SQL_date" value="#form.toDate#">)
    ORDER BY ...
    </cfquery>

<cfelse>  
    <!--- Error handling goes here --->
</cfif>
于 2012-12-02T06:32:37.753 回答
1

正如评论中所建议的,一种更灵活的过滤日期的方法是使用这种方法。无论列是仅包含日期还是包含日期和时间,它都可以工作,并且不会干扰数据库对索引的使用(因为使用日期函数可能)。

    WHERE  TheDateColumn >= TheStartDateAtMidnight         
    AND    TheDateColumn < TheDayAfterEndDateAtMidnight   

例如,如果您想返回日期为 2012 年 12 月 3 日到 12 月 4 日之间任何时间的所有记录

<!--- omitted date validation for brevity ---> 
<cfset form.from_date = "12/03/2012">
<cfset form.to_date   = "12/04/2012">

<cfquery name="getEvents" datasource="#dsn#">
    SELECT  event_date
    FROM    user_activation_events 
    WHERE   event_date >= <cfqueryparam value="#form.from_date#" cfsqltype="cf_sql_date">
    AND     event_date < <cfqueryparam value="#dateAdd('d', 1, form.to_date)#" cfsqltype="cf_sql_date">
    AND     status_code = 1 
</cfquery>


样本数据

    2012-12-02 23:59:59.000
    2012-12-03 00:00:00.000
    2012-12-03 07:34:18.000
    2012-12-04 13:34:18.000
    2012-12-04 23:59:59.000
    2012-12-05 00:00:00.000

结果:

    1 | 2012-12-03 00:00:00.0  
    2 | 2012-12-03 07:34:18.0  
    3 | 2012-12-04 13:34:18.0  
    4 | 2012-12-04 23:59:59.0  



日期注意事项:

但这不起作用,因为日期以这种格式存储在数据库中:yyyy-mm-dd hh:mm:ss

它真的与格式无关。日期时间值的存储方式与您在屏幕上看到的方式不同。这yyyy-mm-dd hh:mm:ss是一个用户友好的字符串,由您使用的任何 IDE 提供,并且可以变化。通常,datetime值实际上存储为数字。该数字通常表示与某个基准日期或纪元的偏移量。在 CF/java 中,它是自unix epoch以来的毫秒数。因此,虽然您的 IDE 可能会向您显示一个人类友好的日期字符串,例如yyyy-mm-dd hh:mm:ss,但在内部它只是一个数字。

将日期查询视为任何数字比较。如果查询没有返回您期望的所有记录,通常是因为您传入的数字之一太大或太小。

 WHERE Col >= 1354510800000   // java.util.Date => {ts '2012-12-03 00:00:00'}
 AND   Col <= 1354683600000   // java.util.Date => {ts '2012-12-05 00:00:00'}
于 2012-12-03T15:59:26.557 回答