I recently ran into a frustrating issue while doing some date comparisons within ColdFusion Query of Queries (QofQ) and selecting records with dates less than a specified date using <cfqueryparam>.
Luckily I was already familiar with the "quirky" behavior of QofQ when it comes to dates and how you need to use createODBCDate() (or createODBCDateTime()) before making comparisons. If you're curious why I'm using cfqueryparam's in my QofQ date comparisons you can find a bunch of articles about why this is done but here's a popular one from Ben Nadel if you're up for some reading: ColdFusion Query of Queries Unexpected Data Type Conversion
Anyway, I came across a slightly different issue where the date comparison was ignoring time differences within the same day. Check this out:
Here's my reference date:
<cfset o.referenceDate = "{ts '2015-11-16 23:59:59'}" />
Here's where I set up a query object (3 rows with 2 dates that come before my reference date and 1 date after)
<cfset o.tempQuery = queryNew("ID,Name,DateCreated","INTEGER,VARCHAR,TIMESTAMP") />
<cfset queryAddRow(o.tempQuery) />
<cfset querySetCell(o.tempQuery, "ID", o.tempQuery.recordcount ) />
<cfset querySetCell(o.tempQuery, "Name", "The Past" ) />
<cfset querySetCell(o.tempQuery, "DateCreated", createODBCDateTime('11/16/2015 1:00:00') ) />
<cfset queryAddRow(o.tempQuery) />
<cfset querySetCell(o.tempQuery, "ID", o.tempQuery.recordcount ) />
<cfset querySetCell(o.tempQuery, "Name", "The Past" ) />
<cfset querySetCell(o.tempQuery, "DateCreated", createODBCDateTime('11/15/2015 1:00:00') ) />
<cfset queryAddRow(o.tempQuery) />
<cfset querySetCell(o.tempQuery, "ID", o.tempQuery.recordcount ) />
<cfset querySetCell(o.tempQuery, "Name", "The Future" ) />
<cfset querySetCell(o.tempQuery, "DateCreated", createODBCDateTime('11/17/2015 1:00:00') ) />
Here's a basic select using createODBCDateTime():
<cfquery dbtype="query" name="o.temp">
SELECT *
FROM o.tempQuery
WHERE DateCreated < #createODBCDateTime(o.referenceDate)#
</cfquery>
<cfdump var="#o.temp#">
Everything works here! I get the values as expected. However, when I try using cfqueryparam things get weird!
<cfquery dbtype="query" name="o.temp">
SELECT *
FROM o.tempQuery
WHERE DateCreated < <cfqueryparam cfsqltype="cf_sql_date" value="#o.referenceDate#" />
</cfquery>
<cfdump var="#o.temp#">
This query can't see that the reference date is greater than the QofQ date ( 2015-11-16 23:59:59 vs 11/16/2015 1:00:00 ). Essentially the query is ignoring the time difference.
After hours of searching and playing around I discovered that you can use a different cfsqltype to make sure it accounts for date and time! That value is "cf_sql_datetime".
This value doesn't seem to exist in either Adobe's ColdFusion9 or ColdFusion 10 online documentation for some reason!
Here's how the final working query looks:
<cfquery dbtype="query" name="o.temp">
SELECT ID, CAST(DateCreated as date) as DateCreated
FROM o.tempQuery
WHERE DateCreated < <cfqueryparam cfsqltype="cf_sql_datetime" value="#o.referenceDate#" />
</cfquery>
<cfdump var="#o.temp#">
TLDR:
You can use an "undocumented" cfsqltype value of cf_sql_datetime value to ensure that your QofQ takes time into consideration when making date comparisons.