如何将参数设置为BIRT报告中的值列表?

Mik*_*ler 8 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 = ?
Run Code Online (Sandbox Code Playgroud)

我想修改查询以允许我指定商店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 (?)
Run Code Online (Sandbox Code Playgroud)

我如何在BIRT中完成此任务?我需要指定什么样的参数?

小智 9

简单的部分是报告参数:将显示类型设置为列表框,然后选中允许多个值选项.

现在困难的部分:遗憾的是,您无法将多值报告参数绑定到数据集参数(至少,不是在版本3.2中,这是我正在使用的).这里有一篇关于BIRT World博客的帖子:http: //birtworld.blogspot.com/2009/03/birt-multi-select-statements.html ,它描述了如何使用代码插件来绑定多选报告参数到报告数据集.

不幸的是,当我尝试它时,它没有用.如果你可以让它工作,那就是我推荐的方法; 如果你不能,那么另一种方法是修改数据集的queryText,在适当的时候将报表参数中的所有值插入到查询中.假设s.id是数字,这是一个可以粘贴到数据源的beforeOpen事件脚本中的函数:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后可以从数据集的beforeOpen事件脚本中调用它,如下所示:

this.queryText = fnMultiValParamSql ( "rpID", "0 /*rpID*/", this.queryText );
Run Code Online (Sandbox Code Playgroud)

假设您的报告参数名为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*/)
Run Code Online (Sandbox Code Playgroud)

脚本中包含0,以便查询脚本在设计时有效,数据集值将正确绑定到报表; 在运行时,这个硬编码的0将被删除.

但是,这种方法可能非常危险,因为它可能使您容易受到SQL注入攻击:http://en.wikipedia.org/wiki/SQL_injection,如下所示:http://xkcd.com/327/.

对于从预定义选项列表中选择的纯数值,不应该进行SQL注入攻击; 但是,在允许参数的自由形式输入字符串的情况下,相同的方法很容易受到攻击.

  • 非常感谢这个解决方案!唯一的标志:当为数据源定义了fnMultiValParamSql函数时,我无法完成这项工作:我将它移动到报告"初始化"事件的设计(根)级别 - 这就像魅力一样:)我还修改了函数:添加了这段代码:if(strSelectedValues ==""){strSelectedValues ="null"; 在此之后,我可以传递可空值,并像这样使用它们:和(userCreator_id in(0/*userList*/)或(0/*userList*/)为null) (2认同)

Sco*_*aum 5

仅供参考:BIRT World文章应该有效(我写过),但这是问题的早期解决方案.

我们已经创建了一个开源插件,您可以将其添加到BIRT,它可以更清晰地解决此问题.birt-functions-lib中的Bind Parameters函数提供了一种从多值参数中进行多选的简单方法.

如果您仍然感兴趣,请查看Eclipse Labs上的birt-functions-lib项目.