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

 找回密码
 注册
查看: 818|回复: 7

[每日一题] PL/SQL Challenge 每日一题:2018-6-28 修改内联视图

[复制链接]
论坛徽章:
496
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期: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:53
跳转到指定楼层
1#
发表于 2018-7-3 05:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

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

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

作者:Steven Feuerstein

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

我有这些书和作者的表:

create table qz_authors (
   id       integer primary key
, name     varchar2(30)
)
/

create table qz_books (
   id       integer primary key
, name     varchar2(30)
, rating   integer
, author   integer references qz_authors
)
/

insert into qz_authors values (1, 'Larry Niven')
/
insert into qz_authors values (2, 'Jerry Pournelle')
/

insert into qz_books values (10, 'Protector'     , 4, 1)
/
insert into qz_books values (11, 'Ringworld'     , 5, 1)
/
insert into qz_books values (12, 'Exile to Glory', 4, 2)
/
insert into qz_books values (13, 'Janissaries'   , 3, 2)
/

commit
/

我想要将作者名为Jerry Pournelle的所有的书的评分都增加1分。

哪些选项执行不出错,并且为Pournelle所写的两本书的RATING列的值增加1,使得选项执行之后,这个测试查询会返回所示的输出:

select b.name, b.rating
  from qz_authors a
  join qz_books b
      on b.author = a.id
where a.name = 'Jerry Pournelle'
order by b.id
/

NAME                               RATING
------------------------------ ----------
Exile to Glory                          5
Janissaries                             4

(A)
update (
   select b.rating
     from qz_authors a
     join qz_books b
         on b.author = a.id
    where a.name = 'Jerry Pournelle'
)
   set rating = rating + 1
/

(B)
update (
   select a.name, b.name, b.rating
     from qz_authors a
     join qz_books b
         on b.author = a.id
    where a.name = 'Jerry Pournelle'
)
   set rating = rating + 1
/

(C)
update (
   select b.rating
     from qz_authors a
     join qz_books b
         on b.author = a.id
    where a.name = 'Jerry Pournelle'
)
   set b.rating = b.rating + 1
/

(D)
update (
   select b.rating
     from qz_authors a
     join qz_books b
         on b.author = a.id
    where a.name = 'Jerry Pournelle'
) c
   set c.rating = c.rating + 1
/

(E)
update qz_books b
   set b.rating = b.rating + 1
  join qz_authors a
      on a.id = b.author
    where a.name = 'Jerry Pournelle'
/

(F)
update (
   select b.rating
     from qz_books b
    where b.author in (
      select a.id
        from qz_authors a
       where a.name = 'Jerry Pournelle'
          )
)
   set rating = rating + 1
/

(G)
update qz_books b
   set b.rating = b.rating + 1
where b.author in (
   select a.id
     from qz_authors a
    where a.name = 'Jerry Pournelle'
       )
/

论坛徽章:
2
秀才
日期:2018-05-22 16:17:26秀才
日期:2018-05-22 16:17:40
2#
发表于 2018-7-3 08:48 | 只看该作者
答案:ABDFG

C:表变量指定错误
E:Oracle没有这种用法,这是MySQL的用法

使用道具 举报

回复
论坛徽章:
293
生肖徽章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
3#
发表于 2018-7-3 09:58 | 只看该作者
  merge into qz_books t
          using (select a.id
                   from qz_authors a
                  where a.name = 'Jerry Pournelle') s
          on (t.author = s.id )
          when matched then
               update
                  set t.rating = t.rating + 1;

使用道具 举报

回复
认证徽章
论坛徽章:
21
林肯
日期:2013-07-30 18:00:55秀才
日期:2018-05-22 15:17:21秀才
日期:2018-05-22 15:21:20技术图书徽章
日期:2018-05-22 15:21:47秀才
日期:2018-05-22 15:21:47秀才
日期:2018-05-22 16:13:08秀才
日期:2018-05-22 16:13:21技术图书徽章
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:13:30技术图书徽章
日期:2018-05-22 15:17:21
4#
发表于 2018-7-3 11:58 | 只看该作者
同时更新2张表的内容就会报错,内联视图只能更新一张表
update (select qb.rating,qb.name,qa.name aut_name
          from qz_books qb, qz_authors qa
         where qb.author = qa.id
         and qa.id=1
         ) C
   set C.rating = C.rating + 1,C.name=C.name||'Test',C.Aut_Name='Sunzheng'

使用道具 举报

回复
论坛徽章:
496
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期: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:53
5#
 楼主| 发表于 2018-7-4 05:22 | 只看该作者
答案ABDFG, 2楼得奖。

A: 在内联视图里,books表是键值保留的(key preserved), 这意味着books表的键也是视图的键。因此,如果你修改的是books表的列(这正是我们所做的)视图是可修改的。
B: 在内联视图中如果选择了其他的列并不要紧,因为我们修改的只是来自books表的一个列,这是没问题的。
C: 表别名B在内联视图之外不可见,所以这会报错:
ORA-00904: "B"."RATING": invalid identifier.
D: 如果给内联视图一个表别名(此处是C),然后用它来修饰列名,这是完全可以的。
E: 为了修改一个连接,我们需要一个真实视图,或这一个内联视图——如果在UPDATE里面直接对表使用JOIN, 这是不支持的。这样会报错:
ORA-00933: SQL command not properly ended.
F: 如果不用JOIN, 我们也可以在内联视图中用一个IN子句来获取我们想要修改的书本清单。
G: 但是在这种情况下我们其实不需要内联视图,我们可以在UDATE语句的WHERE子句中直接使用IN

使用道具 举报

回复
认证徽章
论坛徽章:
21
林肯
日期:2013-07-30 18:00:55秀才
日期:2018-05-22 15:17:21秀才
日期:2018-05-22 15:21:20技术图书徽章
日期:2018-05-22 15:21:47秀才
日期:2018-05-22 15:21:47秀才
日期:2018-05-22 16:13:08秀才
日期:2018-05-22 16:13:21技术图书徽章
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:13:30技术图书徽章
日期:2018-05-22 15:17:21
6#
发表于 2018-7-5 10:32 | 只看该作者
newkid 发表于 2018-7-4 05:22
答案ABDFG, 2楼得奖。

A: 在内联视图里,books表是键值保留的(key preserved), 这意味着books表的键也是 ...

HI ,咨询个问题,就是说的books表是(key preserved),怎么知道的。表定义的吗?,以为我发现,并不是所有的这么写法都行,有的时候就会报,表不是(key preserved)的错误。谢谢指点!

使用道具 举报

回复
论坛徽章:
496
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期: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:53
7#
 楼主| 发表于 2018-7-5 21:53 | 只看该作者
sse_zero 发表于 2018-7-5 10:32
HI ,咨询个问题,就是说的books表是(key preserved),怎么知道的。表定义的吗?,以为我发现,并不是所有 ...

举个例子,你要修改的是A表,也即A是key preserved
那么所有的类似 A JOIN B, 或者 A LEFT JOIN B, 就要求B在连接键上有主键或者唯一约束。
这样才能保证连接后A的一行不会变成多行。
可以同时有多个JOIN, 比如A JOIN B ON ... JOIN C ON ...
都得满足上述条件。
12C好像有所放松,允许B表是一个查询结果,然后在连接键上有GROUP BY操作,这样也能保证唯一。

使用道具 举报

回复
认证徽章
论坛徽章:
21
林肯
日期:2013-07-30 18:00:55秀才
日期:2018-05-22 15:17:21秀才
日期:2018-05-22 15:21:20技术图书徽章
日期:2018-05-22 15:21:47秀才
日期:2018-05-22 15:21:47秀才
日期:2018-05-22 16:13:08秀才
日期:2018-05-22 16:13:21技术图书徽章
日期:2018-05-22 16:13:30秀才
日期:2018-05-22 16:13:30技术图书徽章
日期:2018-05-22 15:17:21
8#
发表于 2018-7-6 09:14 | 只看该作者
newkid 发表于 2018-7-5 21:53
举个例子,你要修改的是A表,也即A是key preserved
那么所有的类似 A JOIN B, 或者 A LEFT JOIN B, 就要 ...

谢谢。明白点了。

使用道具 举报

回复

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

本版积分规则

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