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

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

[每日一题] PL/SQL Challenge 每日一题:2017-7-25 子程序重载中的缺省值

[复制链接]
论坛徽章:
479
状元
日期: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:03:12状元
日期:2015-11-23 10:04:09
发表于 2017-7-28 04:01 | 显示全部楼层 |阅读模式
(原发表于 2011-7-26)

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

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

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

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

作者:Steven Feuerstein

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

我在我的模式下编译了如下的包:

CREATE OR REPLACE PACKAGE plch_pkg
IS
   PROCEDURE show_data (value1_in IN VARCHAR2, value2_in IN NUMBER);

   PROCEDURE show_data (value1_in   IN VARCHAR2
                      , value2_in   IN NUMBER
                      , value3_in   IN BOOLEAN DEFAULT TRUE);
END plch_pkg;
/

CREATE OR REPLACE PACKAGE BODY plch_pkg
IS
   PROCEDURE show_data (value1_in   IN VARCHAR2
                      , value2_in   IN NUMBER
                      , value3_in   IN BOOLEAN DEFAULT TRUE)
   IS
   BEGIN
      DBMS_OUTPUT.put_line (
         value1_in || ' ' || value2_in || ' '
         || CASE value3_in
               WHEN TRUE THEN 'TRUE'
               WHEN FALSE THEN 'FALSE'
               ELSE 'NULL'
            END);
   END;

   PROCEDURE show_data (value1_in IN VARCHAR2, value2_in IN NUMBER)
   IS
   BEGIN
      show_data (value1_in, value2_in, TRUE);
   END;
END plch_pkg;
/

不幸的是,当我试图执行下列代码块:

BEGIN
   plch_pkg.show_data ('Lucky Number?', 4815162342);
   plch_pkg.show_data ('Lucky Number?', 4815162342, FALSE);
END;
/

Oracle 报错了:

PLS-00307: too many declarations of 'SHOW_DATA' match this call

哪些选项描述了我能够对包或者代码块或者两者同时所进行的修改,使得它可以避免这个错误并且显示下列文本:

Lucky Number? 4815162342 TRUE
Lucky Number? 4815162342 FALSE

(A)
BEGIN
   plch_pkg.show_data (value1_in => 'Lucky Number?'
                     , value2_in => 4815162342);

   plch_pkg.show_data (value1_in   => 'Lucky Number?'
                     , value2_in   => 4815162342
                     , value3_in   => FALSE);
END;
/

(B)
把包的定义修改如下:

CREATE OR REPLACE PACKAGE plch_pkg
IS
   PROCEDURE show_data (value1_in IN VARCHAR2, value2_in IN NUMBER);

   PROCEDURE show_data (value1_in   IN VARCHAR2
                      , value2_in   IN NUMBER
                      , value3_in   IN BOOLEAN);
END plch_pkg;
/

CREATE OR REPLACE PACKAGE BODY plch_pkg
IS
   PROCEDURE show_data (value1_in   IN VARCHAR2
                      , value2_in   IN NUMBER
                      , value3_in   IN BOOLEAN)
   IS
   BEGIN
      DBMS_OUTPUT.put_line (
         value1_in || ' ' || value2_in || ' '
         || CASE value3_in
               WHEN TRUE THEN 'TRUE'
               WHEN FALSE THEN 'FALSE'
               ELSE 'NULL'
            END);
   END;

   PROCEDURE show_data (value1_in IN VARCHAR2, value2_in IN NUMBER)
   IS
   BEGIN
      show_data (value1_in, value2_in, TRUE);
   END;
END plch_pkg;
/

(C)
把包的定义修改如下:

CREATE OR REPLACE PACKAGE plch_pkg
IS
   PROCEDURE show_data (value1_in   IN VARCHAR2
                      , value2_in   IN NUMBER
                      , value3_in   IN BOOLEAN DEFAULT TRUE);
END plch_pkg;
/

CREATE OR REPLACE PACKAGE BODY plch_pkg
IS
   PROCEDURE show_data (value1_in   IN VARCHAR2
                      , value2_in   IN NUMBER
                      , value3_in   IN BOOLEAN DEFAULT TRUE)
   IS
   BEGIN
      DBMS_OUTPUT.put_line (
         value1_in || ' ' || value2_in || ' '
         || CASE value3_in
               WHEN TRUE THEN 'TRUE'
               WHEN FALSE THEN 'FALSE'
               ELSE 'NULL'
            END);
   END;
END plch_pkg;
/

(D)
BEGIN
   plch_pkg.show_data ('Lucky Number?', 4815162342);
   plch_pkg.show_data ('Lucky Number?', 4815162342, value3_in => FALSE);
END;
/

论坛徽章:
30
SQL大赛参与纪念
日期:2011-04-13 12:08:17秀才
日期:2017-08-23 14:10:21秀才
日期:2017-08-23 14:10:21技术图书徽章
日期:2017-08-23 14:17:18技术图书徽章
日期:2017-08-23 14:17:18秀才
日期:2017-09-08 11:09:04秀才
日期:2017-09-08 11:09:04秀才
日期:2017-09-08 11:09:04秀才
日期:2017-09-18 17:04:35秀才
日期:2017-09-25 15:09:50
发表于 2017-7-28 08:25 | 显示全部楼层
答案B和C
题里的错误是因为参数定义中[value3_in   IN BOOLEAN DEFAULT TRUE]使得value3_in可缺省,
使得只写两个参数调用show_data时,oracle无法判断要调用的PROCEDURE是[两个参数的]还是[缺省了第三个参数的]。

B 选项去掉了DEFAULT TRUE,避免了缺省带来的混淆
C 把两个函数合在了一起,当然也就不存在混淆了。

A和D只是在参数的写法上做了修改,不能解决PROCEDURE混淆的问题。
带有[参数变量名=> ]是 指定传入哪个变量,参数顺序是可变的
不用[参数变量名=> ]则必须按顺序写参数

使用道具 举报

回复
论坛徽章:
15
秀才
日期:2017-08-11 15:30:05技术图书徽章
日期:2017-08-23 14:17:00秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05
发表于 2017-7-28 09:11 | 显示全部楼层
答案 BC

value3_in 有缺省值,所以程序传入  value1_in, value2_in的时候,oracle分辨不清楚是调用 2个参数的还是3个参数的,此时oracle就会报错。

所以A错误。

B重新编译了,更新了下调用value1_in, value2_in的存储过程,其实他是调用 3个参数的show_data,此时oracle可以唯一确定调用的存储过程。

C的方法更直接,直接去掉传入2个参数的存储过程,这样oracle只会找到唯一的传入3个参数的show_data

D 错误,同A

使用道具 举报

回复
论坛徽章:
15
秀才
日期:2017-08-11 15:30:05技术图书徽章
日期:2017-08-23 14:17:00秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05秀才
日期:2017-08-11 15:30:05
发表于 2017-7-28 09:12 | 显示全部楼层
fatfoxz 发表于 2017-7-28 08:25
答案B和C
题里的错误是因为参数定义中[value3_in   IN BOOLEAN DEFAULT TRUE]使得value3_in可缺省,
使得 ...

哥们,你真早

使用道具 举报

回复
论坛徽章:
30
SQL大赛参与纪念
日期:2011-04-13 12:08:17秀才
日期:2017-08-23 14:10:21秀才
日期:2017-08-23 14:10:21技术图书徽章
日期:2017-08-23 14:17:18技术图书徽章
日期:2017-08-23 14:17:18秀才
日期:2017-09-08 11:09:04秀才
日期:2017-09-08 11:09:04秀才
日期:2017-09-08 11:09:04秀才
日期:2017-09-18 17:04:35秀才
日期:2017-09-25 15:09:50
发表于 2017-7-28 09:34 | 显示全部楼层

公司就要求这么早上班,我也不想啊~~~

使用道具 举报

回复
论坛徽章:
479
状元
日期: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:03:12状元
日期:2015-11-23 10:04:09
 楼主| 发表于 2017-7-29 04:44 | 显示全部楼层
答案BC, 2楼得奖。

AD: 加入参数的名字记号法并不能避免这个问题。错误是由第三个参数的缺省值导致的。所以为任一个调用加入名字记号法并不能解决Oracle第一次调用时对show_data的解释问题。

B: 通过去除第三个参数的缺省值,这两个调用之间对show_data的歧义就不复存在了。

C: 这可能是最优解决方案。其实show_data的第二种实现是没有什么理由的,唯一的区别是你不想为value3_in参数传入一个实际参数值。

尽可能让你的代码简单点!

使用道具 举报

回复
认证徽章
论坛徽章:
0
发表于 2017-9-3 11:48 | 显示全部楼层
大家好  偶是新来的,过来学习 多多指教

使用道具 举报

回复

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

本版积分规则

SACC2017购票8.8折优惠进行时

2017中国系统架构师大会(SACC2017)将于10月19-21日在北京新云南皇冠假日酒店震撼来袭。今年,大会以“云智未来”为主题,云集国内外顶级专家,围绕云计算、人工智能、大数据、移动互联网、产业应用等热点领域展开技术探讨与交流。本届大会共设置2大主会场,18个技术专场;邀请来自互联网、金融、制造业、电商等多个领域,100余位技术专家及行业领袖来分享他们的经验;并将吸引4000+人次的系统运维、架构师及IT决策人士参会,为他们提供最具价值的交流平台。
----------------------------------------
优惠时间:2017年8月30日前

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