Вопрос по sql, jasper-reports, where-clause – Условные предложения 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 Безразлично»t выводит дату в формате, понятном моему SQL-серверу. Я хотел бы, чтобы условное выражение все еще использовало подготовленный оператор с драйвером jdbc и добавлял параметр, я просто хочу, чтобы подготовленный оператор зависел от того, является ли параметр пустым или нет. Можно ли это сделать?

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

Ваш Ответ

3   ответа
1

$X{EQUAL, , }

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

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!{} Вы можете избежать этого с помощью решения ниже.

Я лично нетак не нравится. Это также может привести к плохому плану выполнения.

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

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