2012-09-12 29 views
2

我想问一下是否可以在游标声明中分配一个变量。oracle游标值根据条件的不同而不同

CURSOR cur_name IS <variable_name> 

我想完成的是在游标中where子句的某些部分和select语句的from子句根据另一个select的结果而变化。如下图所示:

select count(*) from table_name 
v_cnt 
where cond1; 

IF V_CNT为0时,光标会:

cursor cur_name IS 
    select * from tab_name1 
    where cond1; 

IF V_CNT> 0时,光标会:

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

我在想,如果我能做到的if-else,然后对将在游标上分配的select进行concat。

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

让我知道你是否需要更多的细节。 欣赏任何反馈。

回答

1

为什么不使用类似

select * 
from tab_name 
WHERE (v_cnt = 0 AND cond1) 
OR  (v_cnt > 0 AND cond2) 
+0

对不起,我认为我超级简化了我的示例...某些条件和表格也会根据v_cnt值进行不同的配置。所以我希望我可以将选择分配给一个变量,并附加任何代码行。 – mysticfalls

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; 
+0

嗨,谢谢你的回答,但是我不认为如果我改变列的话会更有效率,我不得不将它改变为两个游标。:( – mysticfalls

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。它以我的观点描述你的案例。

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); 

它把一切融合在一起,可以比巴拉吉的回答更加混乱。但是有时候最好在一个SQL中拥有所有的逻辑。这可能有助于减少重复逻辑。 (另外,你不需要担心Oracle实际使用这两个查询,并且运行速度很慢,知道有一个绑定变量控制着哪个查询被使用,这足够聪明了。这就是解释中的FILTER步骤)

相关问题