Как прочитать курсор внутри другого курсора в PL / SQL - PullRequest
0 голосов
/ 03 октября 2018

Я должен завершить разработку, сделанную кем-то, кто покинул компанию, я пытаюсь понять курсор, встроенный в другой курсор ... что-то вроде этого:

CURSOR c_fund as select col_1, 
       col_2, 
       CURSOR(select col_10 * {some formula} clo_n, 
                     col_m 
               from table2 
              where col_8 is not null)
(...)

Как мне тогда прочитать внутренний курсор?Когда я выполняю запрос основного курсора, у меня есть такой результат:

COL_1        COL_2   CURSOR
-------      ------  -------
11619187    604441  (CURSOR)
11619187    604434  (CURSOR)
11619187    604439  (CURSOR)

Когда я дважды щелкаю (на TOAD) на данных CURSOR, это открывает новое окно, показывающее данные:

CLO_N   COL_M
-----   ---------------
009511  1g0-M-TPT_BNM
009511  1g0-Q--213_BNM
009511  C--F_R*P_C:R:CT
009511  1g0-M--16_BNM
009511  P*RF_DI-TR
009511  *CR
009511  BOWLING
009511  C--F_BNM
009511  C:PIT:L
009511  N:V
009511  INF--IGN

1 Ответ

0 голосов
/ 03 октября 2018

Переменные курсора на помощь!Посмотрите пример кода ниже.Этого должно быть достаточно для начала работы (опирается на стандартную схему управления персоналом, которую вы можете ввести здесь: https://github.com/oracle/db-sample-schemas).

CREATE OR REPLACE PROCEDURE curexpr_test (
   p_locid NUMBER
)
IS
   TYPE refcursor IS REF CURSOR;

/* Notes on CURSOR expression:

   1. The query returns only 2 columns, but the second column is
      a cursor that lets us traverse a set of related information.

   2. Queries in CURSOR expression that find no rows do NOT raise
      NO_DATA_FOUND.
*/
   CURSOR all_in_one_cur
   IS
      SELECT l.city
            ,CURSOR (SELECT d.NAME
                           ,CURSOR (SELECT e.last_name
                                      FROM employee e
                                     WHERE e.department_id =
                                                            d.department_id)
                                                                  AS ename
                       FROM department d
                      WHERE l.location_id = d.loc_id
                    ) AS dname
        FROM locations l
       WHERE l.location_id = p_locid;

   department_cur   refcursor;
   employee_cur     refcursor;
   v_city           locations.city%TYPE;
   v_dname          department.NAME%TYPE;
   v_ename          employee.last_name%TYPE;
BEGIN
   OPEN all_in_one_cur;

   LOOP
      FETCH all_in_one_cur
       INTO v_city
           ,department_cur;

      EXIT WHEN all_in_one_cur%NOTFOUND;

      -- Now I can loop through deartments and I do NOT need to
      -- explicitly open that cursor. Oracle did it for me.
      LOOP
         FETCH department_cur
          INTO v_dname
              ,employee_cur;

         EXIT WHEN department_cur%NOTFOUND;

         -- Now I can loop through employee for that department.
         -- Again, I do need to open the cursor explicitly.
         LOOP
            FETCH employee_cur
             INTO v_ename;

            EXIT WHEN employee_cur%NOTFOUND;
            DBMS_OUTPUT.put_line (v_city || ' ' || v_dname || ' '
                                  || v_ename
                                 );
         END LOOP;

         CLOSE employee_cur;  
      END LOOP;

      CLOSE department_cur;   
   END LOOP;

   CLOSE all_in_one_cur;
END;
/
...