根据传递给存储过程的参数在两个游标之间切换

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 提出的干净解决方案要慢得多。

【讨论】:

以上是关于根据传递给存储过程的参数在两个游标之间切换的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL SQL:比较两个存储过程返回的引用游标结果

VBA 将日期参数传递给 SQL Server 存储过程

ibatis调存储过程返回游标

oracle数据库的游标和存储过程怎么写?

将表中的列值作为参数传递给存储过程 sql

将 Access 表日期值作为参数传递给 SQL Server 存储过程