Как я устанавливаю параметр на список значений в отчете о BIRT?

У меня есть DataSet с запросом как это:

select s.name, w.week_ending, w.sales 
from store s, weekly_sales_summary w 
where s.id=w.store_id and s.id = ?

Я хотел бы изменить запрос, чтобы позволить мне указывать список идентификаторов хранилища, как:

select s.name, w.week_ending, w.sales 
from store s, weekly_sales_summary w 
where s.id=w.store_id and s.id IN (?)

Как я выполняю это в BIRT? Какой параметр я должен указать?

8
задан Mike Sickler 4 August 2010 в 02:22
поделиться

1 ответ

Легкая часть - это параметр отчета: установите тип отображения List Box, затем отметьте опцию Allow Multiple Values.

Теперь сложная часть: к сожалению, вы не можете связать многозначный параметр отчета с параметром набора данных (по крайней мере, не в версии 3.2, которую я использую). В блоге BIRT World есть сообщение об этом: http://birtworld.blogspot.com/2009/03/birt-multi-select-statements.html , в которой описывается, как использовать плагин кода для привязки параметров отчета с множественным выбором к набору данных отчета.

К сожалению, когда я попробовал, это не сработало. Если вы сможете заставить его работать, я бы рекомендовал именно этот метод; если не сможете, то альтернативой может быть модификация queryText набора данных, чтобы вставить все значения из параметра отчета в запрос в нужный момент. Если предположить, что s.id является числовым, вот функция, которую можно вставить в сценарий события beforeOpen для datasource:

function fnMultiValParamSql ( pmParameterName, pmSubstituteString, pmQueryText )
{
strParamValsSelected=reportContext.getParameterValue(pmParameterName);
strSelectedValues="";
for (var varCounter=0;varCounter<strParamValsSelected.length;varCounter++)
{
    strSelectedValues += strParamValsSelected[varCounter].toString()+",";
}
strSelectedValues = strSelectedValues.substring(0,strSelectedValues.length-1);
return pmQueryText.replace(pmSubstituteString,strSelectedValues);
}

которую затем можно вызвать из сценария события beforeOpen для dataset, например, так:

this.queryText = fnMultiValParamSql ( "rpID", "0 /*rpID*/", this.queryText );

при условии, что ваш параметр отчета называется rpID. Вам нужно будет изменить свой запрос, чтобы он выглядел следующим образом:

select s.name, w.week_ending, w.sales 
from store s, weekly_sales_summary w 
where s.id=w.store_id and s.id IN (0 /*rpID*/)

0 включен в сценарий, чтобы сценарий запроса был действителен во время проектирования, и значения набора данных правильно связывались с отчетом; во время выполнения этот жестко закодированный 0 будет удален.

Однако такой подход потенциально очень опасен, поскольку может сделать вас уязвимым для атак SQL Injection: http://en.wikipedia.org/wiki/SQL_injection , как показано здесь: http://xkcd.com/327/ .

В случае чисто числовых значений, выбранных из предопределенного списка, атака SQL-инъекции невозможна; однако тот же подход уязвим, когда допускается свободный ввод строк для параметра.

9
ответ дан 5 December 2019 в 09:23
поделиться