查看: 1580|回复: 5

[每日一题] PL/SQL Challenge 每日一题:2014-2-10 用记录的值修改数据库

[复制链接]
论坛徽章:
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
发表于 2014-2-12 03:19 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

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

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

作者:Zoltan Fulop

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

我创建了如下的表和数据:
CREATE TABLE plch_from
(
  employee_id   NUMBER
,employee_name VARCHAR2(30)
,salary        NUMBER
)
/

CREATE TABLE plch_to
(
  employee_id   NUMBER
,employee_name VARCHAR2(30)
,salary        NUMBER
)
/

BEGIN
  INSERT INTO plch_from VALUES (1, 'Scott', 1000);
  INSERT INTO plch_from VALUES (2, 'John', 2000);

  INSERT INTO plch_to VALUES (1, NULL, NULL);
  INSERT INTO plch_to VALUES (2, NULL, NULL);

  COMMIT;
END;
/

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

(A)
DECLARE
  TYPE t_tab IS TABLE OF plch_from%ROWTYPE INDEX BY PLS_INTEGER;
  l_tab t_tab;
BEGIN
  SELECT *
    BULK COLLECT INTO l_tab
    FROM plch_from;

  FORALL i IN 1 .. l_tab.COUNT
    UPDATE plch_to
       SET employee_name = l_tab(i).employee_name
          ,salary        = l_tab(i).salary
     WHERE employee_id   = l_tab(i).employee_id;

  DBMS_OUTPUT.put_line( SQL%ROWCOUNT );
END;
/

(B)
DECLARE
  TYPE t_rec IS RECORD (employee_id   DBMS_SQL.number_table
                       ,employee_name DBMS_SQL.varchar2_table
                       ,salary        DBMS_SQL.number_table);
  l_tab t_rec;
BEGIN
  SELECT *
    BULK COLLECT INTO l_tab.employee_id
                     ,l_tab.employee_name
                     ,l_tab.salary
    FROM plch_from;
   
  FORALL i IN 1 .. l_tab.employee_id.COUNT()
    UPDATE plch_to
       SET employee_name = l_tab.employee_name(i)
          ,salary        = l_tab.salary(i)
     WHERE employee_id   = l_tab.employee_id(i);

  DBMS_OUTPUT.put_line( SQL%ROWCOUNT );
END;
/

(C)
DECLARE
  TYPE t_tab IS TABLE OF plch_from%ROWTYPE INDEX BY PLS_INTEGER;
  l_tab t_tab;
BEGIN
  SELECT *
    BULK COLLECT INTO l_tab
    FROM plch_from;

  FORALL i IN 1 .. l_tab.COUNT
    UPDATE plch_to
       SET (employee_name
           ,salary) = (SELECT l_tab(i).employee_name
                             ,l_tab(i).salary
                        FROM dual)
     WHERE employee_id = l_tab(i).employee_id;

  DBMS_OUTPUT.put_line( SQL%ROWCOUNT );
END;
/

(D)
DECLARE
  TYPE t_tab IS TABLE OF plch_from%ROWTYPE INDEX BY PLS_INTEGER;
  l_tab t_tab;
BEGIN
  SELECT *
    BULK COLLECT INTO l_tab
    FROM plch_from;

  FORALL i IN 1 .. l_tab.COUNT
    UPDATE plch_to
       SET row = l_tab(i)
     WHERE employee_id = l_tab(i).employee_id;

  DBMS_OUTPUT.put_line( SQL%ROWCOUNT );
END;
/

(E)
DECLARE
  TYPE t_employee_id_tab IS
    TABLE OF plch_from.employee_id%TYPE INDEX BY PLS_INTEGER;

  TYPE t_rec IS RECORD (employee_name plch_from.employee_name%TYPE
                       ,salary        plch_from.salary%TYPE);
  TYPE t_tab IS TABLE OF t_rec INDEX BY PLS_INTEGER;

  l_employee_id_tab t_employee_id_tab;
  l_tab             t_tab;
  l_index           PLS_INTEGER := 0;
BEGIN
  FOR rec IN (SELECT *
                FROM plch_from)
  LOOP
    l_index := l_index + 1;

    l_employee_id_tab(l_index)   := rec.employee_id;
    l_tab(l_index).employee_name := rec.employee_name;
    l_tab(l_index).salary        := rec.salary;
  END LOOP;

  FORALL i IN 1 .. l_employee_id_tab.COUNT
    UPDATE (SELECT employee_name
                  ,salary
              FROM plch_to
             WHERE employee_id = l_employee_id_tab(i))
       SET row = l_tab(i);

  DBMS_OUTPUT.put_line( SQL%ROWCOUNT );
END;
/

论坛徽章:
142
秀才
日期:2016-01-06 14:01:09秀才
日期:2016-02-18 10:06:46秀才
日期:2016-02-18 10:08:02秀才
日期:2016-02-18 10:08:14秀才
日期:2016-03-01 09:57:08天蝎座
日期:2016-03-18 14:23:56秀才
日期:2016-03-24 09:10:24秀才
日期:2016-03-24 09:20:52秀才
日期:2016-04-21 14:08:53秀才
日期:2016-04-21 14:11:59
发表于 2014-2-12 09:12 | 显示全部楼层
答案B,E

使用道具 举报

回复
论坛徽章:
142
秀才
日期:2016-01-06 14:01:09秀才
日期:2016-02-18 10:06:46秀才
日期:2016-02-18 10:08:02秀才
日期:2016-02-18 10:08:14秀才
日期:2016-03-01 09:57:08天蝎座
日期:2016-03-18 14:23:56秀才
日期:2016-03-24 09:10:24秀才
日期:2016-03-24 09:20:52秀才
日期:2016-04-21 14:08:53秀才
日期:2016-04-21 14:11:59
发表于 2014-2-12 09:27 | 显示全部楼层
A 不能直接引用TABLE%ROWTYPE数组字段(俺的版本是10G,据说11G开始没有这个限制)
B 记录字段可以直接使用
C、D犯了和A一样的错误
E 声明了一个记录数组,可以直接引用

使用道具 举报

回复
招聘 : 数据库开发
论坛徽章:
5
兰博基尼
日期:2013-11-11 12:45:102014年新春福章
日期:2014-02-18 16:47:53马上加薪
日期:2014-02-18 16:47:53优秀写手
日期:2014-03-05 06:00:16马上有钱
日期:2014-03-13 15:21:18
发表于 2014-2-12 10:00 | 显示全部楼层
11g中 ABCDE 都对

使用道具 举报

回复
论坛徽章:
142
秀才
日期:2016-01-06 14:01:09秀才
日期:2016-02-18 10:06:46秀才
日期:2016-02-18 10:08:02秀才
日期:2016-02-18 10:08:14秀才
日期:2016-03-01 09:57:08天蝎座
日期:2016-03-18 14:23:56秀才
日期:2016-03-24 09:10:24秀才
日期:2016-03-24 09:20:52秀才
日期:2016-04-21 14:08:53秀才
日期:2016-04-21 14:11:59
发表于 2014-2-12 10:11 | 显示全部楼层
所以俺说明了俺的版本

使用道具 举报

回复
论坛徽章:
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
 楼主| 发表于 2014-2-13 04:23 | 显示全部楼层
本帖最后由 newkid 于 2014-2-13 04:23 编辑

答案ABCDE, 我一时疏忽忘记说明版本号了,3楼按10G作答,也算对。

A:(推荐)
这个选项用常见的方法来修改表,清楚而且简单。

B:(不推荐)
正确,但不怎么流行。要尽量避免这种语法。

C:(不推荐)
修改能够成功执行,但是本来可以做得更简单。

D:
这个选项用了SET ROW语法,从而修改了一整行数据。(译者注:连主键也会被修改,哪怕你并没有改动主键的值。所以不推荐)

E:
和D不同的是,SET ROW修改的是只包含两个列的内联视图,从而避开了修改主键。

使用道具 举报

回复

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

本版积分规则 发表回复

DTCC2020中国数据库技术大会 限时8.5折

【架构革新 高效可控】2020年9月21日~23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


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