根据传递给存储过程的参数在两个游标之间切换
Posted
技术标签:
【中文标题】根据传递给存储过程的参数在两个游标之间切换【英文标题】:switch between two cursors based on parameter passed into stored procedure 【发布时间】:2010-03-25 10:35:21 【问题描述】:我的过程中有两个游标,它们仅在它们加入的表名上有所不同。 使用的游标由传递给过程的参数确定
if (param = 'A') then
DECLARE CURSOR myCursor IS
SELECT x,y,z
FROM table1 a, table2 b
BEGIN
FOR aRecord in myCursor
LOOP
proc2(aRecord.x, aRecord.y, aRecord.z);
END LOOP;
COMMIT;
END;
elsif (param = 'B') then
DECLARE CURSOR myCursor IS
SELECT x,y,z
FROM table1 a, table3 b -- different table
BEGIN
FOR aRecord in myCursor
LOOP
proc2(aRecord.x, aRecord.y, aRecord.z);
END LOOP;
COMMIT;
END;
end if
我不想为了一张不同的表而重复代码。 有什么改进的建议吗?
提前致谢
【问题讨论】:
【参考方案1】:您可以像这样使用 REF CURSOR(为方便起见,我使用了 EMP 和 DEPT 表):
declare
mycursor sys_refcursor;
param varchar2(1) := 'A';
type arecordtype is record (no integer, name varchar2(30));
arecord arecordtype;
begin
if (param = 'A') then
open mycursor for
select deptno as no, dname as name
from dept;
elsif (param = 'B') then
open mycursor for
select empno as no, ename as name
from emp;
else
raise_application_error(-20001,'Invalid param value: '||param);
end if;
loop
fetch mycursor into arecord;
exit when mycursor%notfound;
dbms_output.put_line(arecord.name);
end loop;
close mycursor;
end;
【讨论】:
【参考方案2】:虽然 Tony Andrews 提出的解决方案是正确的解决方法,但这里有一个快速而简单的替代方法:
DECLARE
param varchar2(1) := 'A';
BEGIN
FOR aRecord IN ( SELECT x,y,z FROM table1 a, table2 b
WHERE a.foo = b.foo /* join condition */
AND param = 'A'
UNION ALL
SELECT x,y,z FROM table1 a, table3 b
WHERE a.foo = b.foo
AND param = 'B' ) LOOP
proc2(aRecord.x, aRecord.y, aRecord.z);
END LOOP;
COMMIT;
END;
显然,这比 Tony 提出的干净解决方案要慢得多。
【讨论】:
以上是关于根据传递给存储过程的参数在两个游标之间切换的主要内容,如果未能解决你的问题,请参考以下文章