查看: 770|回复: 6

[每日一题] PL/SQL Challenge 每日一题:2018-5-14 CURRENT OF子句

[复制链接]
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2018-5-17 04:41 | 显示全部楼层 |阅读模式
(原发表于 2011-9-20)

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

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

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

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

作者:Steven Feuerstein

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

我吃惊了如下的表和数据:

CREATE TABLE plch_employees
(
   employee_id   INTEGER
,  last_name     VARCHAR2 (100)
,  salary        NUMBER
)
/

BEGIN
   INSERT INTO plch_employees
        VALUES (100, 'Jobs', 1000000);

   INSERT INTO plch_employees
        VALUES (200, 'Ellison', 1000000);

   INSERT INTO plch_employees
        VALUES (300, 'Gates', 1000000);

   COMMIT;
END;
/

哪些选项在执行之后会显示 "3"?

(A)
DECLARE
   CURSOR emps_cur
   IS
      SELECT *
        FROM plch_employees
      FOR UPDATE;

   l_count   PLS_INTEGER := 0;
BEGIN
   FOR rec IN emps_cur
   LOOP
      DELETE FROM plch_employees
            WHERE CURRENT OF emps_cur;

      l_count := l_count + SQL%ROWCOUNT;
   END LOOP;

   DBMS_OUTPUT.put_line (l_count);
   ROLLBACK;
END;
/

(B)
DECLARE
   CURSOR emps_cur
   IS
      SELECT *
        FROM plch_employees
      FOR UPDATE;

   l_count   PLS_INTEGER := 0;
BEGIN
   FOR rec IN emps_cur
   LOOP
      DELETE FROM emps_cur
            WHERE CURRENT OF;

      l_count := l_count + SQL%ROWCOUNT;
   END LOOP;

   DBMS_OUTPUT.put_line (l_count);
   ROLLBACK;
END;
/


(C)
DECLARE
   l_count   PLS_INTEGER := 0;
BEGIN
   FOR rec IN (SELECT *
                 FROM plch_employees
               FOR UPDATE)
   LOOP
      DELETE FROM plch_employees
            WHERE CURRENT OF SQL%CURRENT_CURSOR;

      l_count := l_count + SQL%ROWCOUNT;
   END LOOP;

   DBMS_OUTPUT.put_line (l_count);
   ROLLBACK;
END;
/



(D)
DECLARE
   CURSOR emps_cur
   IS
      SELECT *
        FROM plch_employees
      FOR UPDATE;

   l_employee   emps_cur%ROWTYPE;

   l_count      PLS_INTEGER := 0;
BEGIN
   OPEN emps_cur;

   LOOP
      FETCH emps_cur INTO l_employee;

      EXIT WHEN emps_cur%NOTFOUND;

      DELETE FROM plch_employees
            WHERE CURRENT OF emps_cur;

      l_count := l_count + SQL%ROWCOUNT;
   END LOOP;

   DBMS_OUTPUT.put_line (l_count);
   ROLLBACK;
END;
/
论坛徽章:
18
秀才
日期:2018-05-22 16:17:26蒙奇·D·路飞
日期:2018-08-06 09:43:02技术图书徽章
日期:2018-07-23 13:55:45秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:50:14秀才
日期:2018-07-23 13:50:14技术图书徽章
日期:2018-07-23 13:44:34
发表于 2018-5-17 08:46 | 显示全部楼层
答案:AD
A:明显对的
B:语法不对
C:语法不对
D:对,循环的另一种写法

使用道具 举报

回复
论坛徽章:
18
秀才
日期:2018-05-22 16:17:26蒙奇·D·路飞
日期:2018-08-06 09:43:02技术图书徽章
日期:2018-07-23 13:55:45秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:55:25秀才
日期:2018-07-23 13:50:14秀才
日期:2018-07-23 13:50:14技术图书徽章
日期:2018-07-23 13:44:34
发表于 2018-5-17 08:47 | 显示全部楼层
版主,纪念章在哪里看得到?

使用道具 举报

回复
认证徽章
论坛徽章:
34
林肯
日期:2013-07-30 18:00:55技术图书徽章
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:17:26秀才
日期:2018-07-23 13:38:29技术图书徽章
日期:2018-07-23 13:38:40秀才
日期:2018-07-23 13:38:40秀才
日期:2018-07-23 13:44:01秀才
日期:2018-08-31 10:37:01秀才
日期:2018-08-31 10:37:20
发表于 2018-5-17 09:22 | 显示全部楼层
sbw0818 发表于 2018-5-17 08:47
版主,纪念章在哪里看得到?

好像是自动发送。在你头像下面自动有。

使用道具 举报

回复
认证徽章
论坛徽章:
34
林肯
日期:2013-07-30 18:00:55技术图书徽章
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:17:26秀才
日期:2018-07-23 13:38:29技术图书徽章
日期:2018-07-23 13:38:40秀才
日期:2018-07-23 13:38:40秀才
日期:2018-07-23 13:44:01秀才
日期:2018-08-31 10:37:01秀才
日期:2018-08-31 10:37:20
发表于 2018-5-17 09:54 | 显示全部楼层
A.D 学习了。
重温了一下for update 的用处:https://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html
和  WHERE CURRENT OF 用法:https://www.techonthenet.com/oracle/cursors/current_of.php

问下newkid 大哥,是不是这个就是锁定后更新删除这个就是标准写法? select 。。。fro update ..... update/delete when current of.

使用道具 举报

回复
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
 楼主| 发表于 2018-5-18 04:09 | 显示全部楼层
答案AD, 2楼得奖。

A: 这个选项在FOR循环游标用了 WHERE CURRENT OF, 在CURRENT OF后面引用了游标的名字。全都正确, "3" 被显示。
B: 在DELETE语句中的使用的语法是错的,这个代码块会报错:
"PL/SQL: ORA-00931: missing identifier"

有人可能会以为,每次从游标返回一行,所以也许DELETE FROM...WHERE CURRENT OF会简单地引用游标,Oracle会处理好其他的一切。

然而并非如此,你必须在CURRENT OF子句提供一个显式游标的名字。
C: 这个选项试图在游标循环里面的隐式查询使用CURRENT OF, 因为没有游标名字,就在CURRENT OF后面使用"SQL%CURRENT_CURSOR"

想得挺美,但是并不存在这样的SQL隐式游标属性。

这个代码块会报错:
"PL/SQL: ORA-00911: invalid character"

D: 这个选项在显式游标循环中使用WHERE CURRENT OF,在CURRENT OF后面引用了游标名字。全都正确, "3" 被显示。

这个选项告诉我们,你可以在任何形式的循环,而不仅仅是FOR循环,只要你是从显式游标中获取数据。

使用道具 举报

回复
论坛徽章:
326
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2018-5-23 20:57 | 显示全部楼层
select for update   + where current of  

使用道具 举报

回复

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

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表