查看: 3241|回复: 5

[每日一题] PL/SQL Challenge 每日一题:2018-2-22 NULL值

[复制链接]
论坛徽章:
530
奥运会纪念徽章:垒球
日期: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-2-28 05:38 | 显示全部楼层 |阅读模式

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

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

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

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

作者:Steven Feuerstein

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


Oracle 的AskTOM网站最近启动了一个每月一度的办公时间在线问答活动。如果一个会话被批准(下面表中的approved_by_id非空),或者当前用户是主持会话的专家之一,则该会话在网站上可见。

我执行了这些语句:

CREATE TABLE qz_sessions
(
   session_id       INTEGER,
   session_name     VARCHAR2 (100),
   approved_by_id   INTEGER,
   teacher_id       INTEGER,
   teacher2_id      INTEGER,
   teacher3_id      INTEGER
)
/

BEGIN
   INSERT INTO qz_sessions (session_id,
                            session_name,
                            approved_by_id,
                            teacher_id,
                            teacher2_id,
                            teacher3_id)
        VALUES (100,
                'PL/SQL 101',
                NULL,
                1,
                2,
                NULL);
   COMMIT;
END;
/

哪些选项可用来取代下面的 ##REPLACE## ,创建了一个名为QZ_CAN_SEE的函数:

CREATE OR REPLACE FUNCTION qz_can_see (session_id_in   IN INTEGER,
                                       user_id_in      IN INTEGER)
   RETURN BOOLEAN
   AUTHID DEFINER
IS
   l_session   qz_sessions%ROWTYPE;
BEGIN
   SELECT * INTO l_session
     FROM qz_sessions
    WHERE session_id = session_id_in;

   ##REPLACE##
EXCEPTION
   WHEN NO_DATA_FOUND THEN RETURN FALSE;
END;
/


使得下面这个代码块执行之后, "Cannot see session" 在屏幕上仅被显示一次?

BEGIN
   IF NOT qz_can_see (100, 1)
   THEN
      DBMS_OUTPUT.put_line ('Cannot see session');
   END IF;

   IF NOT qz_can_see (NULL, 15)
   THEN
      DBMS_OUTPUT.put_line ('Cannot see session');
   END IF;

   IF NOT qz_can_see (100, NULL)
   THEN
      DBMS_OUTPUT.put_line ('Cannot see session');
   END IF;
END;
/

(A)
RETURN    l_session.approved_by_id IS NOT NULL
          OR user_id_in IN (l_session.teacher_id,
                            l_session.teacher2_id,
                            l_session.teacher3_id);

(B)
RETURN    l_session.approved_by_id > 0
          OR user_id_in = l_session.teacher_id
          OR user_id_in = l_session.teacher2_id
          OR user_id_in = l_session.teacher3_id;

(C)
RETURN    l_session.approved_by_id > 0
          OR user_id_in IN (NVL (l_session.teacher_id, -100),
                            NVL (l_session.teacher2_id, -100),
                            NVL (l_session.teacher3_id, -100));

(D)
RETURN    l_session.approved_by_id IS NOT NULL
          OR NVL (user_id_in IN (l_session.teacher_id,
                            l_session.teacher2_id,
                            l_session.teacher3_id), FALSE);
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2018-2-28 06:49 来自手机 | 显示全部楼层
每个会话都固定3个老师,还是有可能某个为空?

使用道具 举报

回复
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2018-2-28 06:50 来自手机 | 显示全部楼层
问完才发现插入那行就是2个老师

使用道具 举报

回复
论坛徽章:
401
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2018-2-28 06:52 来自手机 | 显示全部楼层
就是看or null的结果

使用道具 举报

回复
论坛徽章:
12
懒羊羊
日期:2018-02-27 22:52:20秀才
日期:2018-05-22 15:21:20秀才
日期:2018-05-22 15:17:21技术图书徽章
日期:2018-05-22 15:17:21秀才
日期:2018-05-22 15:16:47举人
日期:2018-03-01 10:25:45秀才
日期:2018-03-01 10:21:25秀才
日期:2018-03-01 10:13:04秀才
日期:2018-03-01 10:13:04秀才
日期:2018-03-01 10:13:04
发表于 2018-2-28 09:26 | 显示全部楼层
答案:ABC
根据选项return第一个条件返回的都是false 主要看第二个条件or后面的是否返回的为false

使用道具 举报

回复
论坛徽章:
530
奥运会纪念徽章:垒球
日期: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-3-1 07:03 | 显示全部楼层

答案ABC, 5楼得奖。

A: 第一个对qz_can_see的调用返回TRUE, 因为表中找到了一行,而且approved_by_id为NULL, 所以RETURN的第一个子句返回FALSE。但是我们在找到了一个user_id_in和teacher_id的匹配。这个RETURN语句用了OR。"FALSE or TRUE" -> TRUE
第二个对qz_can_see的调用返回FALSE, 因为值为NULL的session_id自动把我们送到了异常处理部分。
第三个对qz_can_see的调用返回NULL,因为approved_by_id 和 user_id_in 的值都是NULL, 所以RETURN语句中的子句取值为NULL, 而
"NULL or NULL" -> NULL

B: 第一个对qz_can_see的调用返回TRUE, 因为表中找到了一行,而且approved_by_id为NULL, 所以RETURN的第一个子句返回FALSE。但是我们在找到了一个user_id_in和teacher_id的匹配。这个RETURN语句用了OR。"NULL or TRUE" -> TRUE
第二个对qz_can_see的调用返回FALSE, 因为值为NULL的session_id自动把我们送到了异常处理部分。
第三个对qz_can_see的调用返回NULL,因为approved_by_id 和 user_id_in 的值都是NULL, 所以RETURN语句中的子句取值为NULL, 而
"NULL or NULL" -> NULL

C: 对approved_by_id > 0的检查永远为NULL, 因为这个会话未获批准,而NULL并不会>0或者<0或者=0
IN 里面的NVL确保列表中的值没有一个为NULL, 但是user_id_in仍然有可能为NULL, 第三个调用就是如此。

所以第一个调用返回TRUE: NULL OR 1 IN (1, 2, -100).
第二个调用返回FALSE, 因为传入的session_id为NULL, NO_DATA_FOUND被抛出。
第三个调用返回NULL因为 "NULL IN (1, 2, -100)" -> NULL.

D:
"Cannot see session" 被显示了两次。
在第一次调用中,TRUE被返回,因为这个会话的teacher_id=1
在第二次调用中,FALSE被返回,因为session_id为NULL直接导致了异常。
在第三次调用中,FALSE还是被返回,因为我现在用了NVL来防止NULL来从这个表达式浮上来。

使用道具 举报

回复

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

本版积分规则 发表回复

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