我有一个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注入攻击; 但是,在允许参数的自由形式输入字符串的情况下,相同的方法很容易受到攻击.
仅供参考:BIRT World文章应该有效(我写过),但这是问题的早期解决方案.
我们已经创建了一个开源插件,您可以将其添加到BIRT,它可以更清晰地解决此问题.birt-functions-lib中的Bind Parameters函数提供了一种从多值参数中进行多选的简单方法.
如果您仍然感兴趣,请查看Eclipse Labs上的birt-functions-lib项目.