2

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

CURSOR cur_name IS <variable_name>

我想要完成的是,在游标中,select 语句的一些 where 子句和 from 子句根据另一个 select 的结果而有所不同。如下所示:

select count(*) from table_name
v_cnt
where cond1;

如果 v_cnt 为 0,则光标为:

 cursor cur_name IS 
    select * from tab_name1
    where cond1;

如果 v_cnt > 0,光标将是:

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

我想知道我是否可以做一个 if-else 然后 concat 将在光标上分配的选择。

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

如果您需要更多详细信息,请告诉我。感谢任何反馈。

4

4 回答 4

2

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

Alexander Tokarev 的回答是最灵活的。但是动态 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);

它将所有内容放在一起,这可能比巴拉吉的答案更令人困惑。但有时最好将所有逻辑都放在一个 SQL 中。它可能有助于减少重复的逻辑。

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

于 2012-09-12T06:41:42.417 回答
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;
于 2012-09-12T05:18:47.743 回答
1

为什么不使用类似的东西

select  * 
from    tab_name 
WHERE   (v_cnt = 0  AND cond1)
OR      (v_cnt > 0  AND cond2)
于 2012-09-12T04:01:36.170 回答
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。它以我的观点描述了你的情况。

于 2012-09-12T06:01:42.433 回答