переключение между двумя курсорами на основе параметра, переданного в хранимую процедуру - PullRequest
0 голосов
/ 25 марта 2010

В моей процедуре есть два курсора, которые отличаются только именем таблицы, к которой они присоединяются. Используемый курсор определяется параметром, переданным в процедуру

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

Я не хочу повторять код ради одной другой таблицы. Любые предложения о том, как улучшить это?

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 25 марта 2010

Вы можете использовать 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;
1 голос
/ 25 марта 2010

Хотя предложенное Тони Эндрюсом решение является правильным способом сделать это, вот несколько быстрых и грязных альтернативных способов:

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;

Очевидно, что это может быть значительно медленнее, чем чистое решение, предложенное Тони.

...