SSRS(RDL) 报告中的 Oracle 参数和 IN 子句



在标记为重复之前,我已经阅读了以下内容:

  • 来自参数的甲骨文"IN 子句"
  • 参数化 SQL IN 子句
  • 在"选择"中使用 Oracle 参数时出现问题

假设我在报表服务器中发布的 .rdl 报表中对我的数据源有此查询:

SELECT ...
FROM ...
WHERE c.cluster_cd IN (:paramClusterCD)

报表生成器 2.0 自动将参数识别为 @paramClusterCD 。在我的 wpf 项目中,我必须创建一个具有多个值的参数,如下所示:

var arrCluster = (lbCluster.SelectedItems.Cast<CLUSTER_MSTR>().ToList()).Select(x => x.CLUSTER_CD).ToArray();
string strCluster = string.Join(",", arrCluster); // result is "1,2,3"

现在,每当我运行(在报告查看器中传递参数)时,我都会遇到此错误:

ORA-01722: invalid number

上一篇文章中的解决方法不起作用,因为这是 SSRS 报告。

它不会以这种方式工作,因为 Oracle 不会识别您实际上正在尝试传入可能值的列表。

你想要的是一个查询,比如

select * from t where x in (1,2,3)

但是你的代码所做的是

select * from t where x = '1,2,3'

由于 x 是数字,Oracle 试图将"1,2,3"转换为数字 - 但失败了......

请参考 AskTom 上的这个优秀线程以获取正确的解决方案(以及关于绑定变量重要性的布道)。

更新:汤姆的第一个答案已经包含了你需要的一切,但它使用了现在已经过时的THE关键字而不是TABLE。因此,以下是应该适合您的步骤:

首先为数字集合创建一个类型

create or replace type TableOfNumber as table of number;

然后创建一个函数来拆分字符串并返回新创建的集合

create or replace function in_list( p_string in varchar2 ) return TableOfNumber as
  l_string        long default p_string || ',';
  l_data          TableOfNumber := TableOfNumber();
  n               number;
begin
  loop
    exit when l_string is null;
    n := instr( l_string, ',' );
    l_data.extend;
    l_data(l_data.count) := to_number( substr( l_string, 1, n-1 ) );
    l_string := substr( l_string, n+1 );
  end loop;
  return l_data;
end;

现在,您可以在查询中使用此函数:

SELECT ...
FROM ...
WHERE c.cluster_cd IN 
 (select * from TABLE (select cast(in_list(:paramClusterCD) as mytableType) from dual))

如果您可以确保传递的参数是数字并且c.cluster_cd是数字列,请尝试以下操作

SELECT ...
FROM ...
WHERE to_char(c.cluster_cd) IN ((:paramClusterCD));

最新更新