如何在PL / SQL中读取另一个游标内的游标

时间:2018-10-03 16:16:52

标签: oracle plsql database-cursor

我必须完成由离开公司的某人所做的开发,我试图理解另一个游标中内置的游标..类似这样的东西:

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 :(得分:5)

将光标变量解救!查看下面的代码示例。这应该给您足够的帮助(依赖于标准的HR模式,您可以从此处进行安装: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;
/