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

Posted

技术标签:

【中文标题】如何在 PL / SQL 中读取另一个游标内的游标【英文标题】:How to read a cursor inside another cursor in PL / SQL 【发布时间】:2018-10-03 16:16:51 【问题描述】:

我必须完成一个离开公司的人所做的开发,我试图理解一个内置在另一个光标内的光标.. 像这样:

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

【问题讨论】:

见here 【参考方案1】:

游标变量来救援!查看下面的代码示例。这应该足以让你继续前进(依赖于标准 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;
/

【讨论】:

感谢@Steven Feuerstein 提供的宝贵帮助,得到如此恰当的解释和如此详细的帮助。

以上是关于如何在 PL / SQL 中读取另一个游标内的游标的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL/SQL 将游标(来自函数)中的每个值一一分配给另一个游标

如何在 Oracle PL/SQL 过程的开始部分之后声明游标

PL/SQL练习显式游标

如何使用两个游标并显示它们 PL/SQL

如何使用 pl/sql 中的游标将多列数据插入包含单列的表中?

在 PL/SQL 中将游标数据提取到数组中