2012-09-07 50 views
6

假设我想要一个JasperReport,如果用户愿意,它可以让用户过滤日期。在SQL如下:。有条件的JasperReports Where子句

select * from foo where bar = $P{bar} and some_date > $P{some.date} 

现在,我不想被一些日期进行过滤,如果他们没有通过的日期在我发现下面的杂牌人们使用:

select * from foo where bar = $P{bar} $P!{some.date.fragment} 

而且some.date.fragment参数定义与下面的默认:

($P{some.date} == null || $P{some.date}.equals("")) ? "" : "AND some_date >'" + new java.sql.Date($P{some.date}.getTime()).toString() + "'" 

这不是为toString工作不输出的日期,我SQL服务器可以理解的格式。我希望条件仍然使用jdbc驱动程序的准备语句并抛出参数,我只是希望准备好的语句依赖于参数是否为null。这可以做到吗?

+0

在我的情况下,第二个参数是一个字符串,where子句我用$ P {} stringValue的的一部分。 –

回答

6

在使用$P!{}表达式之前,JDBC驱动程序会为您进行所有格式化。

但是,如果使用$P!{}表达式,则必须格式化自己。

像这样的东西应该工作:

(
$P{some.date} == null 
? 
"" 
: 
"AND some_date >'" + (new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS")).format($P{some.date}) + "'" 
) 

根据您的数据类型,你必须定制dd.MM.yyyy HH:mm:ss.SSS

如果您不想使用$P!{}表达式,则可以使用下面的解决方案避免它。

我个人不喜欢这种方式。这也可能会导致一个糟糕的执行计划。

如果不想使用$P!{},因为您担心sql注入。只要您的参数$P{some.date}包含像java.lang.Date这样的安全数据类型,就没有必要。


创建参数。让我们把它${is_null_pram}并添加与PARAM类Integer默认表情:

($P{some.date} == null ? 1 : 0) 

现在你可以查询:

SELECT 
    * 
FROM foo 
WHERE 
    bar = $P{bar} 
    AND 
     (
      some_date > $P{some.date} 
      OR 1 = $P{is_null_pram} 
     ) 
+0

那么这些解决方案都不是我想要的理想解决方案。我希望null参数更改正在执行的sql,但我也希望jdbc驱动程序参数化输入。我讨厌搞清楚日期格式等等。然而,第二种选择似乎更好,我用show plan/explain plan做了一些测试,并且数据库处理OR时,如果存在1 = 1的真实条件,则忽略谓词。 –

+0

仅供参考,任何人都可以看到。有'is_null_param'是一个整数,你可以比较另一个1。字符串比较没有得到优化,以及一些数据库。 –

+0

Jup。编辑完成。谢谢。 – edze

1

我想你可以使用的功能:

$X{EQUAL, <column_name>, <parameter_name>}

它会优化查询,您可以在this帮助页面中看到。

0

您可以使用此条件语句

select * 
    from foo 
    where bar = $P{bar} and some_date > $P{some.date} or $P{some.date} is null