PL/SQL - Как создать условный курсор?

Мне нужен условный курсор, например:

  • If a row exists (using WHEN EXISTS or something like this), then my cursor is:
    • CURSOR varCursor IS SELECT 1 a FROM DUAL;
  • Else
    • CURSOR varCursor IS SELECT 2 a FROM DUAL;

Но посмотрите, я не хочу менять результат столбца, я хочу изменить весь курсор.

Ниже я привел более крупный пример.

Спасибо!


Видеть:

SET serveroutput ON SIZE 900000;
DECLARE
  CURSOR varCursor IS SELECT 1 a FROM DUAL;
  -- CURSOR varCursor IS SELECT 2 a FROM DUAL;
BEGIN
  FOR varRow IN varCursor LOOP
    dbms_output.put_line('row: ' || varRow.a);
  END LOOP;
  dbms_output.put_line('Done.');  
END;

person Topera    schedule 19.10.2010    source источник


Ответы (2)


запрещая помещать его в один запрос (как рекомендует Тони), поскольку вам нужен один результат курсора, вы можете сделать это как таковой (это переключит курсор на нужную вам логику -> одно решение курсора)

DECLARE
  PROCEDURE CURSORCHOICE(ITEM IN NUMBER) IS
      L_REFCUR SYS_REFCURSOR;
    returnNum number;
    BEGIN
        IF NVL(ITEM,0) > 0 THEN
            OPEN L_REFCUR FOR
            SELECT ITEM * level  FROM DUAL 
            CONNECT BY LEVEL < ITEM ;
        ELSE
            OPEN L_REFCUR FOR
            SELECT  ITEM -  LEVEL  FROM DUAL 
            connect by level < -1 * ITEM ;  
        END IF;
        dbms_output.put_line('Results to item ' || item);
      loop
         fetch l_refcur into returnNum;
         exit when l_refcur%notfound;
         dbms_output.put_line(returnNum);
      end loop;
      CLOSE L_REFCUR;

    END ;
BEGIN
CURSORCHOICE(5);
CURSORCHOICE(-5);
end ;
/

Results to item 5
5
10
15
20
Results to item -5
-6
-7
-8
-9
person Harrison    schedule 19.10.2010

Буквально, вы можете сделать это:

CURSOR varCursor IS SELECT 1 a FROM DUAL WHERE EXISTS (...)
                    UNION
                    SELECT 2 a FROM DUAL WHERE NOT EXISTS (...);

Однако было бы проще и, возможно, эффективнее иметь 2 курсора и открывать любой из них.

person Tony Andrews    schedule 19.10.2010