如何在查询(BIRT)中动态替换where子句?

时间:2016-02-19 06:14:33

标签: sql where-clause birt

在我的报告查询中,我有一个where子句,需要根据前端选择的数据动态替换。

查询类似于:

在哪里?=?

我已经有一个替换值的代码 - 我创建了报告参数并链接到了值?在查询中。

实施例: 其中name =?

来自前端的任何名称值都会取代?在where子句中 - 这很好。

但是现在我需要替换整个子句(其中?=?)。我应该创建两个参数并将它们链接到'?' ?

2 个答案:

答案 0 :(得分:5)

不,遗憾的是,大多数数据库引擎不允许使用查询参数来处理动态列名。这是出于安全考虑。

所以你需要在查询中保留一个任意的列名:

where name=?

然后在" beforeOpen"数据集的脚本替换名称'报告参数值:

this.queryText=this.queryText.replace("name",params["myparameter"].value);

为防止SQLIA,我建议在此脚本中测试参数的值。有很多方法可以做到这一点,但白名单是最强的测试,例如:

var column=params["myparameter"].value;
if (column=="name" || column=="id" || column=="account" || column=="mycolumnname"){
  this.queryText=this.queryText.replace("name",column);
}

答案 1 :(得分:0)

除了Dominique的回答和你的评论之外,你还需要一个更高级的逻辑。 例如,您可以命名动态列名称 - 值对(column1,value1),(column2,value2)等等。在查询的静态文本中,确保为value1,value2等具有绑定变量(例如,使用Oracle SQL,使用语法

with params as (
  select :value1 as value1,
         :value2 as value2 ... 
  from dual
)
select ... 
from params, my_table 
where 1=1 
and ... static conditions....

然后,在beforeOpen脚本中,根据需要在循环中向查询文本追加条件(循环作为练习留给读者,并且出于安全原因不要忘记检查列名!):

this.queryText += " and " + column_name[i] + "= params.value" + i;

这样您仍然可以使用绑定变量作为比较值。