一尘不染

JasperReports中的条件Where子句

sql

假设我想要一个JasperReport,它可以让用户根据需要过滤日期。SQL如下:

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
Server可以理解的格式输出日期。我想让条件条件仍然与jdbc驱动程序一起使用一条准备好的语句,并将参数扔进去,我只希望准备好的语句依赖于该参数是否为null。能做到吗?


阅读 173

收藏
2021-05-05

共1个答案

一尘不染

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

但是,如果使用$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 class的默认表达式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}
        )
2021-05-05