为什么我的mysql查询没有看到这两个变量的组合,但看到其余的?

时间:2013-06-11 19:11:20

标签: coldfusion

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

<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>

以下是url.end_date = ""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而其余部分失败的结构。

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分:2)

(来自评论..)

  

<cfif IsDefined('url.start_end')>

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

另外,您可能希望为变量设置默认值,以便消除某些cfif条件。然后努力简化逻辑的其余部分,因为它似乎比必要的更复杂...... Dan's response包含一些好的建议。我强烈怀疑你可以通过删除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>