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

 找回密码
 注册
查看: 2888|回复: 5

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

[复制链接]
论坛徽章:
496
目光如炬
日期:2015-11-22 22:00:00秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21探花
日期:2016-01-06 14:11:18进士
日期:2016-01-06 14:11:18
发表于 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);
论坛徽章:
399
优秀写手
日期:2013-12-18 09:29:08itpub13周年纪念徽章
日期:2014-09-28 10:55:55itpub13周年纪念徽章
日期:2014-10-01 15:27:22itpub13周年纪念徽章
日期:2014-10-09 12:04:18马上有钱
日期:2014-10-14 21:37:37马上有钱
日期:2015-01-22 00:39:13喜羊羊
日期:2015-02-20 22:26:07懒羊羊
日期:2015-02-21 22:03:31懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
发表于 2018-2-28 06:49 来自手机 | 显示全部楼层
每个会话都固定3个老师,还是有可能某个为空?

使用道具 举报

回复
论坛徽章:
399
优秀写手
日期:2013-12-18 09:29:08itpub13周年纪念徽章
日期:2014-09-28 10:55:55itpub13周年纪念徽章
日期:2014-10-01 15:27:22itpub13周年纪念徽章
日期:2014-10-09 12:04:18马上有钱
日期:2014-10-14 21:37:37马上有钱
日期:2015-01-22 00:39:13喜羊羊
日期:2015-02-20 22:26:07懒羊羊
日期:2015-02-21 22:03:31懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
发表于 2018-2-28 06:50 来自手机 | 显示全部楼层
问完才发现插入那行就是2个老师

使用道具 举报

回复
论坛徽章:
399
优秀写手
日期:2013-12-18 09:29:08itpub13周年纪念徽章
日期:2014-09-28 10:55:55itpub13周年纪念徽章
日期:2014-10-01 15:27:22itpub13周年纪念徽章
日期:2014-10-09 12:04:18马上有钱
日期:2014-10-14 21:37:37马上有钱
日期:2015-01-22 00:39:13喜羊羊
日期:2015-02-20 22:26:07懒羊羊
日期:2015-02-21 22:03:31懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
发表于 2018-2-28 06:52 来自手机 | 显示全部楼层
就是看or null的结果

使用道具 举报

回复
论坛徽章:
11
懒羊羊
日期:2018-02-27 22:52: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-03-01 10:05:18
发表于 2018-2-28 09:26 | 显示全部楼层
答案:ABC
根据选项return第一个条件返回的都是false 主要看第二个条件or后面的是否返回的为false

使用道具 举报

回复
论坛徽章:
496
目光如炬
日期:2015-11-22 22:00:00秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21探花
日期:2016-01-06 14:11:18进士
日期:2016-01-06 14:11:18
 楼主| 发表于 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文档 | IT博客
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛 | SAP ERP系统
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表