JasperReports 1.3.2
Рубрика: JasperReports | 18 April 2007, 08:26 | juriy
30-го марта вышел новый релиз JasperReports http://www.jasperforge.org/index.php?option=com_content&task=view&id=286&Itemid=214 . Кроме исправления ошибок и улучшения существующей функциональности JasperReports 1.3.2 представил две новых языковых конструкции $P!{…} и $X{…}.
Оба новых элемента нацелены на поддержку динамических запросов в шаблоне отчета. Напомню, что в предыдущих релизах в элементе queryString можно было использовать значения параметров ($P{…}). В таком случае параметры трактовались как bind переменные (знаки “?” в PreparedStatement). Другими словами, существенно изменить структуру запроса было нельзя.
С выходом JasperReports 1.3.2 ситуация изменилась. С помощью синтаксиса $P!{имя_параметра} в запрос можно передавать параметры, которые будут трактоваться, как текст запроса.
Вторая конструкция $X{…} упрощает работу с выражениями IN (…) и NOT IN(…) – когда количество параметров неизвестно до момента наполнения отчета.
Ниже приведен фрагмент примера из стандартной поставки JasperReports 1.3.2:
[xml]
…
ORDER BY $P!{OrderClause}]]>
…
[/xml]
[java]
…
List excludedCities = new ArrayList();
excludedCities.add(“Boston”);
excludedCities.add(“Chicago”);
excludedCities.add(“Oslo”);
parameters.put(“ExcludedCities”, excludedCities);
parameters.put(“OrderClause”, “City”);
if (TASK_FILL_IGNORE_PAGINATION.equals(taskName)) {
parameters.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
}
JasperFillManager.fillReportToFile(fileName, parameters, getConnection());
System.err.println(“Filling time : ” + (System.currentTimeMillis() – start));
System.exit(0);
…
[/java]
Если с синтаксисом $P!{…} все довольно просто (по сути, он ничем не отличается от $P{…}, то $X{…} я рассмотрю немного детальнее.
Итак, $X{…}, как впрочем и $P{} используется исключительно в элементе queryString. Синтаксис $X{…} – такой:
$X{IN, имя_поля, включения}
$X{NOTIN, имя_поля, исключения}
Литералы IN и NOTIN указывают какое действие следует выполнить: включение (IN) или исключение (NOTIN).
имя_поля – название поля в запросе, над которым следует произвести действие.
включения, исключения – это List значений, которые необходимо включить/исключить.

Крута! Спасибо! То, что искали!
Thanks!
Подскажите, а как правильно в репорте, использующий в качестве источника данных XML написать запрос. Я написал вот таким образом но у меня что то не получилось
//ITEMS/ITEM[@ITEMNO $X{NOTIN, @ITEMNO, ExcludedITEM}]
пробовал также
//ITEMS/ITEM[$X{NOTIN, @ITEMNO, ExcludedITEM}]
я понимаю что это такой вид слоупока потому что предыдущий комент был 3 года назад :) но я попробую
1) Можно ли использовать в тексте sql-запроса переменные
Ну например, есть такой код
WHERE T.CODE = $V{MY_VAR}
где $V{MY_VAR} скажем java.lang.String, которая инициализируется строкой “216″
данная конструкция компилируется нормально, но при выполнении отчета валится с ошибкой
“…
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][t4][1061][10303][3.62.56] Синтаксическая ошибка в условии ESCAPE. Подробности смотрите в прикрепленном модуле Throwable. ERRORCODE=-4463, SQLSTATE=42601
…”
на форуме Jasperа люди пишут, что у них такие конструкции работают (может ли это от того, что у меня DB2?)
2) Правда ли что в параметрах я не могу иметь доступа ни к полям запроса, ни к переменных, потому что параметры создаются до них?
3) есть ли возможность в дефолтное значение параметра засунуть РЕЗУЛЬТАТ произвольного запроса, не связанного с основным запросом отчета.
ИМЕННО РЕЗУЛЬТАТ потому, что конструкция вида P!{} не работает (по крайней мере у меня?)
4) откуда растут ноги вопроса 3 попробую объяснить
есть параметр запроса PERIOD_CODE – пользователь вводит это значение выбором из существующей таблицы базы данных
CODE :: NAME
216 :: 01.2012
217 :: 02.2012
218 :: 03.2012
(это чтобы было понятно какбы месяц года в формате строки ММ.ГГГГ), в параметре оказывается строка например “216″
в следующем параметре (целое число) пользователь вводит день месяца
на основании этих двух параметров я пытаюсь сформировать дату которую надо передать в основной запрос что-то типа ENDDATE >
последний вариант который я попробовал и на котором сломался окончательно был такой:
TIMESTAMP_FORMAT(CAST(YEAR((SELECT PRD1.ENDDATE FROM ENERGY.PERIOD PRD1 WHERE PRD1.CODE = $P{PERIOD_CODE})) AS VARCHAR)||”-”CAST(MONTH((SELECT PRD1.ENDDATE FROM ENERGY.PERIOD PRD1 WHERE PRD1.CODE = $P{PERIOD_CODE})) AS VARCHAR)||”-”CAST($P{DAY_OF_CALC} AS VARCHAR)||” 00:00:00″, ‘YYYY-MM-DD HH24:MI:SS’)
5) особенно интересует можно ли в параметре $P!{CHECK_DATE}
организовать проверку что дата введенная пользователем
$P{DAY_OF_CALC}
которая находится внутри периода будет больше чем дата окончания действия договора EPCUSTOMER.CONTRACTENDDATE
то есть в дефолтное значение параметра P{CHECK_DATE} я помещал код
($P{ALL_DAYS} == 1 ? “AND EPC.CONTRACTENDDATE > PRD.ENDDATE” : “AND CAST(EPC.CONTRACTENDDATE AS DATE) > TIMESTAMP_FORMAT(CAST(YEAR((SELECT PRD1.ENDDATE FROM ENERGY.PERIOD PRD1 WHERE PRD1.CODE = $P{PERIOD_CODE})) AS VARCHAR)||\”-\”CAST(MONTH((SELECT PRD1.ENDDATE FROM ENERGY.PERIOD PRD1 WHERE PRD1.CODE = $P{PERIOD_CODE})) AS VARCHAR)||\”-\”CAST($P{DAY_OF_CALC} AS VARCHAR)||\” 00:00:00\”, ‘YYYY-MM-DD HH24:MI:SS’)” )
однако этот вариант не работает