Вопрос по sql, where-clause, jasper-reports – Условные предложения Where в JasperReports

6

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

В моем случае вторым параметром была строка и часть предложения where, которую я использовал $ P {stringValue}. Rodol Velasco

Ваш Ответ

3   ответа
0

    select * 
    from foo 
    where bar = $P{bar} and some_date > $P{some.date} or $P{some.date}  is null
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!{} Вы можете избежать этого с помощью решения ниже.

I personally don't like this way. It also may cause a bad execution plan.

Если вы не хотите использовать$P!{} потому что вы беспокоитесь о инъекции SQL. Это не нужно, пока ваш параметр$P{some.date} содержит безопасный тип данных, какjava.lang.Date.

Создать параметр. Давайте назовем это${is_null_pram} и добавить выражение по умолчанию с классом paramInteger:

($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}
        )
Ну, ни одно из этих решений не является идеальным решением. Я хочу, чтобы нулевой параметр изменил выполняемый sql, но я также хочу, чтобы драйвер jdbc параметризовал ввод. Ненавижу выяснять форматирование даты и т. Д. Второй вариант кажется более подходящим, хотя я провел некоторое тестирование с показом плана / объяснения плана, и базы данных надлежащим образом обрабатывают ИЛИ, игнорируя предикат при наличии истинного условия 1 = 1. Daniel Moses
+1 за обнаружение инъекции SQL.
Просто к сведению тех, кто это видит. Естьis_null_param быть целым числом, которое вы сравниваете с другим 1. Сравнение строк не оптимизируется также некоторыми базами данных. Daniel Moses
Юп. Редактирование завершено. Спасибо.
1

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

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

Похожие вопросы