ITPUB论坛-中国最专业的IT技术社区

 找回密码
 注册
查看: 2842|回复: 3

[每日一题] PL/SQL Challenge 每日一题:2017-1-18 嵌套游标

[复制链接]
论坛徽章:
453
秀才
日期:2015-08-18 09:49:27举人
日期:2015-09-09 10:34:21秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01状元
日期:2015-09-09 10:34:21榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01
发表于 2017-1-21 04:41 | 显示全部楼层 |阅读模式

最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

每两周的优胜者可获得itpub奖励的技术图书一本。

以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808

原始出处:
http://www.plsqlchallenge.com/

作者:Steven Feuerstein

运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品

我执行了下列语句:

CREATE TABLE plch_locations
(
   location_id   NUMBER (4),
   city          VARCHAR2 (30)
)
/

CREATE TABLE plch_departments
(
   department_id     NUMBER (4),
   department_name   VARCHAR2 (30),
   location_id       NUMBER (4)
)
/

CREATE TABLE plch_employees
(
   employee_id     NUMBER (6),
   last_name       VARCHAR2 (25),
   department_id   NUMBER (4)
)
/

BEGIN
   INSERT INTO plch_locations VALUES (1, 'Chicago');
   INSERT INTO plch_locations VALUES (2, 'Bangalore');
   INSERT INTO plch_locations VALUES (3, 'Sao Paolo');

   INSERT INTO plch_departments VALUES (10, 'Construction', 1);
   INSERT INTO plch_departments VALUES (20, 'Destruction', 2);
   INSERT INTO plch_departments VALUES (30, 'Weaving', 3);

   INSERT INTO plch_employees VALUES (100, 'Jimminycricket', 10);
   INSERT INTO plch_employees VALUES (200, 'Flibbidywidget', 20);
   INSERT INTO plch_employees VALUES (300, 'Supercallafradja', 30);

   COMMIT;
END;
/

用每个选项的代码取代下列代码中的"##REPLACE##":

DECLARE
   CURSOR all_in_one_cur
   IS
      SELECT l.city,
             CURSOR (SELECT d.department_name,
                            CURSOR (SELECT e.last_name
                                      FROM plch_employees e
                                     WHERE e.department_id = d.department_id)
                               AS ename
                       FROM plch_departments d
                      WHERE l.location_id = d.location_id)
                AS dname
        FROM plch_locations l
       ORDER BY l.city;

   department_cur   SYS_REFCURSOR;
   employee_cur     SYS_REFCURSOR;

   l_city           plch_locations.city%TYPE;
   l_dname          plch_departments.department_name%TYPE;
   l_ename          plch_employees.last_name%TYPE;
BEGIN
   OPEN all_in_one_cur;

##REPLACE##

END;
/

哪些选项使得代码块执行之后会显示下列文本:

Bangalore Destruction Flibbidywidget
Chicago Construction Jimminycricket
Sao Paolo Weaving Supercallafradja


(A)
   LOOP
      FETCH all_in_one_cur INTO l_city, department_cur;
      EXIT WHEN all_in_one_cur%NOTFOUND;

      LOOP
         FETCH department_cur INTO l_dname, employee_cur;
         EXIT WHEN department_cur%NOTFOUND;

         LOOP
            FETCH employee_cur INTO l_ename;
            EXIT WHEN employee_cur%NOTFOUND;

            DBMS_OUTPUT.put_line (l_city || ' ' || l_dname || ' ' || l_ename);
         END LOOP;
      END LOOP;
   END LOOP;

(B)
   LOOP
      FETCH all_in_one_cur INTO l_city, department_cur;
      EXIT WHEN all_in_one_cur%NOTFOUND;

      LOOP
         FETCH department_cur INTO l_dname, employee_cur;
         EXIT WHEN department_cur%NOTFOUND;

         LOOP
            FETCH employee_cur INTO l_ename;
            EXIT WHEN employee_cur%NOTFOUND;

            DBMS_OUTPUT.put_line (l_city || ' ' || l_dname || ' ' || l_ename);
         END LOOP;

         CLOSE employee_cur;
      END LOOP;

      CLOSE department_cur;
   END LOOP;

   CLOSE all_in_one_cur;

(C)
   LOOP
      FETCH all_in_one_cur INTO l_city, department_cur;
      EXIT WHEN all_in_one_cur%NOTFOUND;

      OPEN department_cur;

      LOOP
         FETCH department_cur INTO l_dname, employee_cur;
         EXIT WHEN department_cur%NOTFOUND;

         OPEN employee_cur;

         LOOP
            FETCH employee_cur INTO l_ename;
            EXIT WHEN employee_cur%NOTFOUND;

            DBMS_OUTPUT.put_line (l_city || ' ' || l_dname || ' ' || l_ename);
         END LOOP;

         CLOSE employee_cur;
      END LOOP;

      CLOSE department_cur;
   END LOOP;

   CLOSE all_in_one_cur;


论坛徽章:
5
2013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:43:09马上有钱
日期:2014-02-18 16:43:09美羊羊
日期:2015-03-04 14:52:282015年新春福章
日期:2015-03-06 11:58:18
发表于 2017-1-21 08:45 | 显示全部楼层
本帖最后由 wbhkkk 于 2017-1-21 16:47 编辑

答案应该是A、B, FETCH all_in_one_cur INTO l_city, department_cur;和FETCH department_cur INTO l_dname, employee_cur; 已经把department_cur和employee_cur打开了
,而C重复打开了应该会报错。

使用道具 举报

回复
论坛徽章:
453
秀才
日期:2015-08-18 09:49:27举人
日期:2015-09-09 10:34:21秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01状元
日期:2015-09-09 10:34:21榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01秀才
日期:2015-09-09 10:33:01
 楼主| 发表于 2017-1-24 05:52 | 显示全部楼层
答案AB, 2楼编辑了自己的帖子,所以答案无效。以后可以发一个新帖进行纠正或者补充。

A: 没有必要关闭任何一个的游标。all_in_one_cur在本地声明并打开,所以当代码块终止的时候它会被关闭。当这个游标被关闭,所有通过fetch打开的嵌套也会被关闭。
B:
在这个选项中,我在每个循环结束的时候关闭了游标变量。我可以这么做,一点问题也没有,但这不是必要的。Oracle会自动关闭游标,并在下次获取的时候再次打开,最后对all_in_one_cur的CLOSE会关闭所有打开的嵌套游标。
C: 这个选项会报错:

ORA-06550: line 28, column 7:
PLS-00382: expression is of wrong type
ORA-06550: line 28, column 7:
PL/SQL: SQL Statement ignored
ORA-06550: line 34, column 10:
PLS-00382: expression is of wrong type
ORA-06550: line 34, column 10:

这是由于试图打开游标变量department_cur和employee_cur。当数据被获取的时候,它们已经被Oracle打开了。但是错误并没有说“游标已经打开”。相反,它报错是因为:

  OPEN cursor_name;
这不是游标变量的有效语法,应该是:

  OPEN cursor_name FOR …;

使用道具 举报

回复
认证徽章
论坛徽章:
15
ERP板块每日发贴之星
日期:2007-08-24 01:03:56狮子座
日期:2015-09-10 09:07:23处女座
日期:2015-09-11 10:28:03ITPUB14周年纪念章
日期:2015-10-26 17:23:44喜羊羊
日期:2015-06-24 14:33:00慢羊羊
日期:2015-06-15 14:22:442015年新春福章
日期:2015-03-12 17:22:46优秀写手
日期:2014-11-20 06:00:13茶鸡蛋
日期:2013-06-29 22:37:49蛋疼蛋
日期:2013-04-27 10:34:16
发表于 2017-1-24 10:03 | 显示全部楼层
想问一下,嵌套游标的优点是什么?一般用在什么地方?好像多年来重没有使用过~

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

久等啦!10张门票开启你的DTCC2017之旅~

2017中国数据库技术大会将于2017年5月11-13日如约而至,本届大会以“数据驱动•价值发现”为主题,共设定2大主场和21个技术专场,云集海内外120+位技术大牛,共同探讨Oracle、MySQL、NoSQL、云端数据库、区块链、深度学习等领域的前瞻性热点话题。
即日起,填写DTCC2017会前调查问卷,即有机会赢取价值2600元的大会门票1张!仅限10张!
----------------------------------------
活动截止时间:2017年5月5日统一公布

问卷入口>>
TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 虎吧 老博客 知识索引树 读书频道 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛 | SAP ERP系统
CopyRight 1999-2011 itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表