oracle游标值因条件而异

时间:2012-09-12 03:58:29

标签: sql oracle stored-procedures cursor conditional

我想询问是否可以在游标声明上分配变量。

CURSOR cur_name IS <variable_name>

我想要实现的是,在游标中,一些where子句和select语句的from子句根据另一个select的结果而变化。如下所示:

select count(*) from table_name
v_cnt
where cond1;

如果v_cnt为0,则光标为:

 cursor cur_name IS 
    select * from tab_name1
    where cond1;

IF v_cnt&gt; 0,光标将是:

    cursor cur_name IS 
    select * from tab_name2
    where cond1
    and cond2;

我想知道我是否可以执行if-else,然后对将在光标上分配的选择进行连接。

    cursor cur_name IS 
    select * from tab_name
    if v_cnt > 0
    where cond2;
    else 
    where cond1;

如果您需要更多详细信息,请与我们联系。 感谢任何反馈。

4 个答案:

答案 0 :(得分:2)

有很多方法可以做到这一点,并且涉及许多权衡。

亚历山大·托卡列夫的回答是最灵活的。但是动态SQL可能很棘手,依赖性问题不会在编译时显示出来等等.Balaji Sukumaran的答案不那么灵活,但更简单,并且将代码分解成更小的块。

如果选择的列始终相同,则可以使用如下方法:

cursor cur_name(v_cnt number) is
select *
from tab_name1
where 1=1 /*condition 1*/
    and v_cnt > 0
---------
union all
---------
select *
from tab_name2
where 2=2 /*condition 2*/
    and (v_cnt is null or v_cnt <= 0);

它把所有东西放在一起,这比Balaji的回答更令人困惑。但有时最好将所有逻辑放在一个SQL中。它可能有助于减少重复逻辑。

(另外,你不必担心Oracle实际上使用这两个查询,并且运行缓慢。很聪明,知道有一个绑定变量可以控制使用哪个查询。这就是FILTER步骤在解释计划中。)

答案 1 :(得分:1)

为什么不使用

之类的东西
select  * 
from    tab_name 
WHERE   (v_cnt = 0  AND cond1)
OR      (v_cnt > 0  AND cond2)

答案 2 :(得分:1)

你正在寻找这样的东西吗?

DECLARE
  V_CNT VARCHAR2(20);

  CURSOR C1
  IS
  SELECT * from Tab1;

  CURSOR C2
  IS
  SELECT * from Tab2;   

BEGIN
  SELECT COUNT(*) INTO V_CNT FROM Table_Name;
    IF V_CNT > 0 THEN
       OPEN C1;
         --code
        Close C1;
    ELSE
       OPEN C2;
          --code
       CLOSE C2;
    END IF;
 END;

答案 3 :(得分:1)

如果光标非常动态,请使用以下内容:

 declare
  c sys_refcursor;
  <here declare the record you would like fetch results to> 
 begin
  open c for 'you query in quotes as the string that you created before regarding your     conditions';
  loop
   FETCH c INTO your record;
   EXIT WHEN c%NOTFOUND;
  end loop;
 end;

无论如何要查看http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/sqloperations.htm#BABFEJED。它根据我的观点描述了你的情况。