我需要从用户那里获得输入,该输入将被传递给查询并与现有值AA进行比较。如果是AA,那么将选择ABC模式。
以下查询正常,
select distinct a.TABLE_OWNER,a.table_name,a.index_name,b.column_name
from dba_indexes a, dba_ind_columns b
where a.index_name=b.index_name
and a.table_name = b.table_name
and a.table_owner in ( case when &user_input = 'AA' then 'ABC' end )
order by 1,2,3,4;
但如果我不得不再提一个架构名称,比如DEF,我该怎么办呢。我尝试使用逗号,但它抛出错误,"缺少右括号"
select distinct a.TABLE_OWNER,a.table_name,a.index_name,b.column_name
from dba_indexes a, dba_ind_columns b
where a.index_name=b.index_name
and a.table_name = b.table_name
and a.table_owner in ( case when &user_input = 'AA' then 'ABC','DEF' end )
order by 1,2,3,4;
错误
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 5 Column: 63
我从Ask Tom网站上读到,只返回一个标量值,是否可以返回一堆值?
答案 0 :(得分:1)
不要使用case
。我想你打算:
and ( &user_input <> 'AA' or a.table_owner in ('ABC','DEF') )
这是猜测。当前代码更像是:
and ( &user_input = 'AA' and a.table_owner in ('ABC','DEF') )
因为case
没有else
子句。
答案 1 :(得分:1)
据我所知,CASE
表达式必须生成单个标量值。但您可以按如下方式重写WHERE
子句:
where
a.index_name = b.index_name and
a.table_name = b.table_name and
(&user_input = 'AA' and
a.table_owner in ('ABC', 'DEF') )
答案 2 :(得分:1)
这是在WHERE子句中使用CASE的正确方法。
...
and case &user_input when 'AA' then case when a.table_owner in ('ABC', DEF') then 1 end
else case when <your other conditions here> then 1 end
end
= 1
工作原理:
首先将&user_input
与AA&#39;进行比较。如果为true,则将a.table_owner
与&#39; ABC&#39;进行比较。和&#39; DEF&#39;,如果它们中的一个CASE
表达式的值为1,否则为NULL(默认情况下)。如果&user_input
不是&#39; AA&#39; (它也可能是NULL),然后评估你没有说明的其他条件,如果为true,则CASE
表达式的计算结果为1,否则为NULL。
然后将CASE
表达式的结果与数字1进行比较。
一个好处是:如果&#34;其他条件&#34;由于短路评估,如果&user_input
是&#39; AA&#39;这种安排是昂贵的(很多计算,诸如此类),这种安排保证它们不会被执行。如果您仅使用AND
和OR
运算符编写条件,则无此控制。
另请注意外部CASE中的CASE表达式的NESTING - 这在许多情况下都非常有效且有用。