1

我编写了一个带有日期条目的脚本,并且由于某种原因,每当我指定一个带有空白结束日期的开始日期时,查询就永远不会选择它。这是我写的。

<cfquery name="stec_mysql_loan_tracking_qry" result="meta_tracking" datasource="STLinux1MySQL">
    Select
        tslo.created,
        tslo.created_by,
        tslo.last_modified,
        tslo.last_modified_by,
        tslo.active,
        tslo.is_manager,
        tslo.pick_userid,
        tslo.customer_code,
        tslo.name,
        tst.user_ip as ip,
        tsl.loan_identifier,
        tst.command,
        tsl.tax_search_loan_id as id
    From
        tax_search_loan_officers tslo Left Join
        tax_search_loans tsl On tsl.tax_search_loan_officer_id =
        tslo.tax_search_loan_officer_id Left Join
        tax_search_track tst On tst.pick_userid = tslo.pick_userid
    Where
        tslo.customer_code In (<cfqueryparam value="#tw_custcodes#" cfsqltype="cf_sql_varchar" list="yes">)
        <cfif IsDefined('url.active')>
            <cfif url.active neq "">
                AND
                tslo.active = <cfqueryparam value="#Trim(url.active)#" cfsqltype="cf_sql_varchar" list="yes">
            </cfif>
        </cfif>

        <cfif IsDefined('url.is_managed')>
            <cfif url.is_managed neq "">
                AND
                tslo.is_manager = <cfqueryparam value="#Trim(url.is_managed)#" cfsqltype="cf_sql_varchar" list="yes">
            </cfif>
        </cfif>

        <cfif IsDefined('url.start_end')>
            <cfif url.start_date neq "" and url.end_date eq "">
                AND
                <cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date"> <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
                AND
                DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d')
            </cfif>
        </cfif>

        <cfif IsDefined('url.start_date')>
            <cfif url.end_date neq "" and url.start_date eq "">
                AND
                '2012-01-01' <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
                AND
                DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= <cfqueryparam value="#Trim(url.end_date)#" cfsqltype="cf_sql_date">
            </cfif>
        </cfif>

        <cfif isDefined('url.start_date')>
            <cfif (url.start_date neq "") and (url.end_date neq "")>
                AND
                <cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date"> <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
                AND
                DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= <cfqueryparam value="#Trim(url.end_date)#" cfsqltype="cf_sql_date">
            </cfif>
        </cfif>
</cfquery>

这是它所看到的 if url.end_date = ""but url.start_date = a value

Select
  tslo.created,
  tslo.created_by,
  tslo.last_modified,
  tslo.last_modified_by,
  tslo.active,
  tslo.is_manager,
  tslo.pick_userid,
  tslo.customer_code,
  tslo.name,
  tst.user_ip as ip,
  tsl.loan_identifier,
  tst.command,
  tsl.tax_search_loan_id as id
From
  tax_search_loan_officers tslo Left Join
  tax_search_loans tsl On tsl.tax_search_loan_officer_id =
    tslo.tax_search_loan_officer_id Left Join
  tax_search_track tst On tst.pick_userid = tslo.pick_userid
Where
  tslo.customer_code In (?)

但是,其他所有组合都很好。我尝试过重写这些cfif块,但这个结构是唯一一个获得 2/3 而其余部分失败的结构。

4

2 回答 2

2

这可能不是原因,但您正在混合数据类型。这个:

and <cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date"> 
   <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') 

比较运算符的左侧有一个日期,右侧有一个字符串。即使它运行没有错误,您也可能会得到意想不到的结果。至少,从右侧删除 date_format 函数。

然后我们有这个:

AND DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d')

至少它将字符串与字符串进行比较,但效率低下。在整体方案中,也许你想要这样的东西:

and tslo.last_modified >=
 <cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date">
and tslo.last_modified =< now()
于 2013-06-11T19:44:06.763 回答
2

(来自评论..)

<cfif IsDefined('url.start_end')>

看起来您有三个日期变量url.start_dateurl.end_dateurl.start_end。什么是url.start_end- 是错字吗?

顺便说一句,您可能希望为变量设置默认值,以便消除一些 cfif 条件。然后努力简化其余的逻辑,因为它似乎比必要的复杂...... 丹的回应包含一些很好的建议。我强烈怀疑您可以通过删除语句来简化代码并使查询更有效地启动DATE_FORMAT(ColumnName, '%Y-%m-%d'),因为它们会阻止数据库正确利用引用列上的索引。


更新:

仔细观察后,我认为这就是代码试图完成的任务:

  • 如果两个日期都存在,则过滤给定的值
  • 如果存在一个日期,则为缺少的日期应用默认值。然后过滤这两个值。
  • 如果两个日期都不存在,则跳过过滤。

这些方面的东西应该模仿当前代码的行为。请注意,它使用这种类型的比较作为处理“时间”问题的更索引友好的方式:

    WHERE column >= {startDateAtMidnight}        
    AND   column <  {dayAfterEndDateAtMidnight}

例子:

<!--- default both to something that is NOT a valid date --->
<cfparam name="url.start_date" default="">
<cfparam name="url.end_date" default="">

<!--- 
    If at least ONE of the dates was supplied, apply 
    the desired defaults for missing values 
--->
<cfif isDate(url.start_date) || isDate(url.end_date)>
    <cfset url.start_date = isDate(url.start_date) ? url.start_date : "some default like 2012-01-01 here">
    <cfset url.end_date = isDate(url.end_date) ? url.end_date : now()>
</cfif>

<cfquery ....>
   SELECT ...
   FROM   ...
   WHERE  ...

   <!--- apply the filter when both dates are populated.  --->
   <cfif isDate(url.start_date) and isDate(url.end_date)>
        AND  tslo.last_modified >= <cfqueryparam value="#url.start_date#" cfsqltype="cf_sql_date">
        AND  tslo.last_modified < <cfqueryparam value="#dateAdd('d', 1, url.end_date)#" cfsqltype="cf_sql_date">
   </cfif>
 </cfquery>
于 2013-06-11T20:30:52.533 回答