查询2个日期之间的记录

时间:2017-06-09 13:53:17

标签: sql sql-server-2012 coldfusion

我有一个页面,我想运行一些关于使用ColdFusion和SQL Server数据库的报告。

这是我的表格:

<cfform name="dateRange" action="" method="POST">

   <label>Date From</label><br>
   <cfinput type="DateField" name="dFrom"  mask="DD/MM/YYYY">

   <label>Date To</label><br>
   <cfinput type="DateField" name="dTo" mask="DD/MM/YYYY">

   <cfinput type="submit" value="Submit" name="Submit">
</cfform>

<hr>

<cfif isDefined("form.submit")>
   <cfinclude template="data-p.cfm">
</cfif> 

data-p.cfm文件如下所示:

<cfset fromDate = #CREATEODBCDATETIME(#form.dFrom#)#>
<cfset toDate = #CREATEODBCDATETIME(#form.dTo#)#>

<cfquery name="t">
    SELECT id, type, started 
    FROM   t_users 
    WHERE  started >= #fromDate# 
    AND    started <= #toDate# 
    ORDER  BY started
</cfquery>

<cfdump var="#t#">

但问题是它会转储所有记录并且不会应用日期过滤器。当我转储查询时,它会转储数据库中的所有记录。即使SQL转储声明,它也会忽略WHERE语句:

 SELECT id, type, started 
 FROM   t_users 
 WHERE  started >= {ts '2017-01-06 00:00:00'} 
 AND    started <= {ts '2017-08-06 00:00:00'} 
 ORDER BY started 

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

  

它会转储所有记录,并且不会应用日期过滤器。

应用日期过滤器。这不是你期望的那个。

我怀疑您正在尝试查找日期为2017年6月1日至6月8日的记录。但是,如果仔细查看生成的sql,它实际上是在2017年1月6日至8月6日过滤。

  

where started >= {ts '2017-01-06 00:00:00'} and started <= {ts '2017-08-06 00:00:00'}

原因是标准CF日期功能仅了解美国日期惯例,即月份优先。所以当你输入一个类似&#34; 01/06 / 2017&#34;的字符串时,它将被解释为 January 6th - 而不是6月1日。要正确处理非美国日期字符串,

  • 使用区域设置敏感函数,例如LSParseDateTime()(具有适当的区域设置)。例如:

    <cfset form.dFrom = "01/06/2017">
    <cfset writeDump( LSParseDateTime(form.dFrom, "de_DE") )>
    
  • 或者对于数字日期,请使用ParseDateTime()和相应的掩码:

    <cfset form.dFrom = "01/06/2017">
    <cfset writeDump( ParseDateTime(form.dFrom, "dd/MM/yyyy") )>
    

请记住,CF的日期函数在他们认为有效的日期字符串中是非常慷慨的,所以您可能想要添加一些额外的验证。

此外,出于性能原因,请始终对任何变量查询参数使用cfqueryparam。更灵活的日期比较方法是:

  WHERE started >= <cfqueryparam value="#someStartDate#" cfsqltype="cf_sql_date"> 
  AND   started < <cfqueryparam value="#dateAdd('d', 1, someEndDate)#" cfsqltype="cf_sql_date"> 

答案 1 :(得分:0)

进一步编辑。当包含在data-p.cfm中时,以下代码必须正常工作:

<cfset fromDay = listGetAt(form.dFrom, 1, "/")>
<cfset fromMonth = listGetAt(form.dFrom, 2, "/")>
<cfset fromYear = listGetAt(form.dFrom, 3, "/")>
<cfset ToDay = listGetAt(form.dTo, 1, "/")>
<cfset ToMonth = listGetAt(form.dTo, 2, "/")>
<cfset ToYear = listGetAt(form.dTo, 3, "/")>

<cfset fromDate = createdate(fromYear,fromMonth,fromDay)>
<cfset toDate = createdate(ToYear,ToMonth,ToDay)>

<cfquery name="t">
    SELECT id, type, started 
    FROM t_users 
    WHERE started >= <cfqueryparam value="#fromDate#" cfsqltype="cf_sql_date">  
    AND started <= <cfqueryparam value="#toDate#" cfsqltype="cf_sql_date">  
    ORDER BY started
</cfquery>