您可以将运算符列表作为参数吗?

Can you have a list of operators as a parameter?

我正在创建一个报告,用户可以在其中 select 他们想在查询中使用哪个运算符来比较两个数字。这可以在 SSRS 中完成吗?

我认为最好使用 case 语句。像这样,其中 total_count 是一个字段,:Total_Allowed_Parm 是他们从下拉菜单中选择的数字。

WHERE total_count CASE  
                     WHEN :Operator_Parm = '=' THEN =
                     WHEN :Operator_Parm = '<' THEN <
                     WHEN :Operator_Parm = '>' THEN >
                     WHEN :Operator_Parm = '<=' THEN <=
                     WHEN :Operator_Parm = '>=' THEN >=
                     ELSE <>
                  END  :Total_Allowed_Parm  

由于 Oracle 没有布尔数据类型,而 case 是一个表达式,您需要手动进行所有检查。像这样:

select *
from your_table
where
  case
    when :Operator_Parm = '=' and total_count = :Total_Allowed_Parm then 1
    when :Operator_Parm = '>=' and total_count >= :Total_Allowed_Parm then 1
    when :Operator_Parm = '>' and total_count > :Total_Allowed_Parm then 1
    /*Other comparisons go here*/
  end is not null

请注意,以上所有内容都不处理空值:在 SQL 中没有任何内容(包括 null 本身)既不等于也不不等于 null

或者 SSRS 中可能有一些机制,可以直接在 SQL 文本中嵌入(执行 SQL 注入)所选值,但我不知道。

您不需要 CASE 表达式:

WHERE (:Operator_Parm = '=' AND total_count = :Total_Allowed_Parm)
OR    (:Operator_Parm = '<' AND total_count < :Total_Allowed_Parm)
OR    (:Operator_Parm = '>' AND total_count > :Total_Allowed_Parm)
OR    (:Operator_Parm = '<=' AND total_count <= :Total_Allowed_Parm)
OR    (:Operator_Parm = '>=' AND total_count >= :Total_Allowed_Parm)
OR    (:Operator_Parm NOT IN ('=', '<', '>', '<=', '>=')
       AND total_count <> :Total_Allowed_Parm)

您还可以使用数据集查询的表达式生成器将运算符直接放入 SQL。

="SELECT *
FROM your_table
WHERE total_count " & Parameters!OPERATOR.Value & " " & Parameters!Total_Allowed_Parm.Value 

这确实留下了 SQL 注入的可能性,但如果您使用带有值列表的参数到 select,用户将无法在参数中键入任何内容。

因此,您正在将 total_count(来自某个地方 - 可能是子查询)与输入值 :total_allowed_parm 进行比较,并且您希望比较使用也传入的比较运算符作为输入值,:operator_parm?

您可以使用 XML 工具来执行此操作,特别是 XQuery 表达式求值。像这样的东西(使用 HR 架构中的标准 EMPLOYEES table 进行说明):

让我们看看每年有多少新员工。 (还没有条件。)

select extract(year from hire_date) as yr, count(*) as total_count
from   hr.employees
group  by extract(year from hire_date)
order  by yr
;

  YR TOTAL_COUNT
---- -----------
2001           1
2002           7
2003           6
2004          10
2005          29
2006          24
2007          19
2008          11

现在让我们传入一个比较运算符和一个比较数字。例如,我们允许用户(通过选择 >=10)查找在哪些年份有 10 名或更多雇员。

首先,声明并初始化绑定变量(使用 SQL*Plus,或者 - 在我的例子中 - SQL Developer 中的“运行 作为脚本”工具):

variable total_allowed_parm number
execute :total_allowed_parm := 10

variable operator_parm varchar2(2)
execute :operator_parm := '>='

那么这里是查询。在 with 子句中,首先我将 - 作为子查询 - 上面显示的查询:按年计算雇用人数。第二个子查询准备用于评估的 XQuery 表达式。

with
  prep (yr, total_count) as (
    select extract(year from hire_date), count(*)
    from   hr.employees
    group  by extract(year from hire_date)
  )
, xml_prep (yr, total_count, comparison) as (
    select yr, total_count, total_count || :operator_parm || :total_allowed_parm
    from   prep
  )
select yr, total_count
from   xml_prep
where  xmlcast(xmlquery(comparison returning content) as varchar2(5)) = 'true'
order  by yr
;

  YR TOTAL_COUNT
---- -----------
2004          10
2005          29
2006          24
2007          19
2008          11

请记住,如果您在 SQL Developer 中执行此操作,并且如我所示定义和初始化绑定变量,则需要 运行 SQL 语句“作为脚本" (F5) - 否则您将需要在提示符下输入绑定(如果您使用 Ctrl+Enter 运行 "as statement")。