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

 找回密码
 注册
查看: 6873|回复: 6

[每日一题] PL/SQL Challenge 每日一题:2017-6-13 在取数据的中间进行提交

[复制链接]
论坛徽章:
480
榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09
发表于 2017-6-17 05:10 | 显示全部楼层 |阅读模式
(原发表于 2011-7-11)

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

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

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

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

作者:        koko

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

我创建了如下的表和数据:

CREATE TABLE plch_num(n NUMBER(1))
/

BEGIN
  INSERT INTO plch_num
       VALUES (1);

  INSERT INTO plch_num
       VALUES (2);

  INSERT INTO plch_num
       VALUES (3);

  COMMIT;
END;
/

我执行下列代码块之后会显示什么?

DECLARE
   l_number   plch_num.n%TYPE;

   CURSOR l_cursor
   IS
      SELECT * FROM plch_num
       ORDER BY n;
BEGIN
   OPEN l_cursor;

   FETCH l_cursor INTO l_number;

   IF l_cursor%FOUND
   THEN
      DBMS_OUTPUT.put_line (l_number);
   END IF;

   DELETE FROM plch_num;

   COMMIT;

   LOOP
      FETCH l_cursor INTO l_number;

      EXIT WHEN l_cursor%NOTFOUND;

      DBMS_OUTPUT.put_line (l_number);
   END LOOP;

   CLOSE l_cursor;
END;
/


(A)
1
2
3

(B)
1

(C)
1
1
2
3


(D)
先会显示"1", 后面跟着一个异常:
ORA-01002: fetch out of sequence

论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
发表于 2017-6-17 10:30 来自手机 | 显示全部楼层
答案是D 由于有commit cursor就失效了

使用道具 举报

回复
认证徽章
论坛徽章:
0
发表于 2017-6-17 21:57 | 显示全部楼层
答案是D
OPEN l_cursor;
FETCH l_cursor INTO l_number;
IF l_cursor%FOUND
   THEN
      DBMS_OUTPUT.put_line (l_number);
   END IF;
DELETE FROM plch_num;
COMMIT;
当执行到这里的时候,plch_num表中的数据已经被全部删除,
下面的循环就会出错

使用道具 举报

回复
论坛徽章:
19
迷宫蛋
日期:2011-11-25 14:00:47秀才
日期:2017-06-29 10:16:48秀才
日期:2017-03-02 10:30:35秀才
日期:2017-03-02 10:30:14托尼托尼·乔巴
日期:2017-01-25 09:38:19暖羊羊
日期:2015-06-15 10:03:48天枰座
日期:2015-07-18 17:23:542015年新春福章
日期:2015-03-06 11:57:31喜羊羊
日期:2015-03-04 14:49:39蛋疼蛋
日期:2013-06-21 13:21:23
发表于 2017-6-18 16:01 | 显示全部楼层
答案A.
open cursor以后,会记录cursor的scn.
即使后面delete并且提交了. cursor会通过undo获取一致性读数据.

使用道具 举报

回复
求职 : 数据库开发
论坛徽章:
16
优秀写手
日期:2014-02-27 06:00:13弗兰奇
日期:2017-07-04 09:16:01秀才
日期:2017-06-29 10:16:48乌索普
日期:2017-05-26 08:58:24娜美
日期:2017-05-18 16:07:23ITPUB15周年纪念
日期:2017-05-02 15:22:36妮可·罗宾
日期:2017-04-06 10:06:19处女座
日期:2016-03-10 09:03:26白羊座
日期:2015-10-09 16:42:50慢羊羊
日期:2015-06-15 21:49:18
发表于 2017-6-18 21:43 | 显示全部楼层
A ,open游标的时候,数据肯定已经在内存里了.不然外面有其他程序同时操作表岂不是矛盾了.
C 不对,1已经被fetch了

使用道具 举报

回复
论坛徽章:
263
乌索普
日期:2016-07-29 01:46:29射手座
日期:2016-05-26 14:02:50双子座
日期:2016-05-25 16:05:44白羊座
日期:2016-05-23 11:49:19双鱼座
日期:2016-04-29 17:13:05秀才
日期:2016-04-29 15:03:39秀才
日期:2016-04-29 15:04:10技术图书徽章
日期:2016-04-29 15:04:10秀才
日期:2016-03-28 10:21:13巨蟹座
日期:2016-03-26 21:14:25
发表于 2017-6-19 09:46 | 显示全部楼层
验证一把:

SQL>
SQL> CREATE TABLE plch_num(n NUMBER(1))
  2  /
Table created
SQL> BEGIN
  2    INSERT INTO plch_num
  3         VALUES (1);
  4  
  5    INSERT INTO plch_num
  6         VALUES (2);
  7  
  8    INSERT INTO plch_num
  9         VALUES (3);
10  
11    COMMIT;
12  END;
13  /
PL/SQL procedure successfully completed

SQL> set serveroutput on;
SQL>
SQL>
SQL> DECLARE
  2     l_number   plch_num.n%TYPE;
  3  
  4     CURSOR l_cursor
  5     IS
  6        SELECT * FROM plch_num
  7         ORDER BY n;
  8  BEGIN
  9     OPEN l_cursor;
10  
11     FETCH l_cursor INTO l_number;
12  
13     IF l_cursor%FOUND
14     THEN
15        DBMS_OUTPUT.put_line (l_number);
16     END IF;
17  
18     DELETE FROM plch_num;
19  
20     COMMIT;
21  
22     LOOP
23        FETCH l_cursor INTO l_number;
24  
25        EXIT WHEN l_cursor%NOTFOUND;
26  
27        DBMS_OUTPUT.put_line (l_number);
28     END LOOP;
29  
30     CLOSE l_cursor;
31  END;
32  /
1
2
3
PL/SQL procedure successfully completed

SQL>


由此可见4楼是对的。。。

使用道具 举报

回复
论坛徽章:
480
榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09
 楼主| 发表于 2017-6-20 07:49 | 显示全部楼层
答案A, 4楼得奖。

A: 三次取到三个不同的数。正确!
B: 如果DELETE和COMMIT会影响到游标返回的数据,那么这就对了。然而Oracle的一致读模式确保这不会发生。
C: 如果COMMIT之后会“重置”游标的结果集,这个答案就对了。但是这并没有发生。
D: 如果游标中的SELECT语句包含“FOR UPDATE”子句,这个错误就会发生。因为它并没有带这个选项,游标不会在行上加锁,所以COMMIT不会打断游标的获取(虽然你会得到“脏数据”,这取决于你程序的逻辑)

使用道具 举报

回复

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

本版积分规则

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