【问题标题】: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

我不想为了一张不同的表而重复代码。 有什么改进的建议吗?

提前致谢

【问题讨论】:

    标签: stored-procedures plsql oracle10g


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

      【讨论】:

        猜你喜欢
        • 2016-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-13
        • 2018-01-07
        • 2016-04-05
        相关资源
        最近更新 更多