您可以将运算符列表作为参数吗?
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")。
我正在创建一个报告,用户可以在其中 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")。