7

假设我想要一个 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 服务器理解的格式输出日期。我想让条件仍然使用带有 jdbc 驱动程序的准备好的语句并将参数折腾进去,我只希望准备好的语句依赖于参数是否为空。这可以做到吗?

4

3 回答 3

6

在您使用$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}
        )
于 2012-09-10T17:20:51.873 回答
1

我认为您可以使用以下功能:

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

如您在此帮助页面中所见,它优化了查询。

于 2012-12-28T16:51:30.667 回答
0

您可以使用此条件语句

    select * 
    from foo 
    where bar = $P{bar} and some_date > $P{some.date} or $P{some.date}  is null
于 2012-12-31T09:31:18.027 回答