我想询问是否可以在游标声明上分配变量。
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;
如果您需要更多详细信息,请与我们联系。 感谢任何反馈。
答案 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。它根据我的观点描述了你的情况。