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

发布于 2024-08-26 16:41:02 字数 673 浏览 6 评论 0原文

我的过程中有两个游标,它们仅在它们连接到的表名称上有所不同。 使用的游标由传递到过程中的参数确定,

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

我不想为了一个不同的表而重复代码。 关于如何改进这一点有什么建议吗?

提前致谢

I have two cursors in my procedure that only differ on the table name that they join to.
The cursor that is used is determined by a parameter passed into the procedure

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

I don't want to repeat the code for the sake of one different table.
Any suggestions on how to improve this?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

指尖上得阳光 2024-09-02 16:41:02

您可以像这样使用 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;

You can use a REF CURSOR like this (I used the EMP and DEPT tables for convenience):

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;
暗藏城府 2024-09-02 16:41:02

尽管托尼·安德鲁斯提出的解决方案是正确的方法,但这里有一个快速而肮脏的替代方法:

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;

显然,这可能比托尼提出的干净解决方案慢得多。

Though Tony Andrews proposed solution is the right way to do it, here is a little quick-and-dirty alternative way:

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;

Obviously, this can be considerably slower than the clean solution proposed by Tony.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文