Условные предложения Where в JasperReports

предположим, я хочу JasperReport, который позволяет пользователю фильтровать дату, если они этого хотят. SQL выглядит следующим образом:

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

теперь я не хочу фильтровать по какой-то дате, если они не передали дату. Я нашел следующий kludge, который люди используют:

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 и бросало параметр, я просто хочу, чтобы подготовленный оператор зависел от того, является ли параметр нулевым или нет. Можно ли это сделать?

3 ответов


прежде чем вы используете $P!{} expression драйвер 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}
        )

Я думаю, вы можете использовать функцию:

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

это оптимизирует запрос, как вы можете видеть в этой страница справки.


вы можете использовать этот условный оператор

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