查看: 5296|回复: 5

[每日一题] 有奖活动:PL/SQL Challenge 每日一题:2012-4-30 对象的自定义构造函数

[复制链接]
论坛徽章:
519
奥运会纪念徽章:垒球
日期: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
跳转到指定楼层
1#
发表于 2012-5-2 04:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

最快答对且答案未经编辑的puber将获得彩蛋章一枚(编辑过的答案不算),其他会员如果提供有价值的分析、讨论也可获得彩蛋章一枚。

以往旧题索引:
http://www.itpub.net/thread-1499223-1-1.html

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

作者:Steven Feuerstein
难度:高


我创建了如下的对象类型来帮我计算PL/SQL代码的执行时间:

CREATE OR REPLACE TYPE plch_timer_t AS OBJECT
(
   timer_name VARCHAR2 (2000),
   start_time INTEGER,
   MEMBER PROCEDURE start_timer,
   MEMBER PROCEDURE stop_timer
);
/

CREATE OR REPLACE TYPE BODY plch_timer_t
AS
   MEMBER PROCEDURE start_timer
   IS
   BEGIN
      SELF.start_time := DBMS_UTILITY.get_time;
   END;

   MEMBER PROCEDURE stop_timer
   IS
   BEGIN
      DBMS_OUTPUT.put_line (
         DBMS_UTILITY.get_time - start_time);
   END;
END;
/

有了这个类型定义,我可以用如下方法来使用它:
DECLARE
   l_timer plch_timer_t :=
      plch_timer_t ('plch_proc performance', NULL);

   PROCEDURE plch_proc IS
   BEGIN
      null;
   END;
BEGIN
   l_timer.start_timer;
   plch_proc;
   l_timer.stop_timer;
END;
/

但我不想在调用timer_t构造函数的时候传递NULL参数;那是start_timer过程里面的设置。哪些选项提供了修改plch_timer_t定义的方法,从而使得下列代码块能够成功执行?

DECLARE
   l_timer plch_timer_t :=
      plch_timer_t ('plch_proc performance');

   PROCEDURE plch_proc IS
   BEGIN
      null;
   END;
BEGIN
   l_timer.start_timer;
   plch_proc;
   l_timer.stop_timer;
END;
/

(A)
CREATE OR REPLACE TYPE plch_timer_t AS OBJECT
(
   timer_name VARCHAR2 (2000),
   PRIVATE start_time INTEGER,
   MEMBER PROCEDURE start_timer,
   MEMBER PROCEDURE stop_timer
);
/

(B)
CREATE OR REPLACE TYPE plch_timer_t AS OBJECT
(
   timer_name VARCHAR2 (2000),
   start_time INTEGER DEFAULT NULL,
   MEMBER PROCEDURE start_timer,
   MEMBER PROCEDURE stop_timer
);
/

(C)
把这个加入到类型规格(type specification)定义:
CONSTRUCTOR FUNCTION plch_timer_t (
   self            IN OUT plch_timer_t,
   timer_name_in   IN     VARCHAR2)
   RETURN SELF AS RESULT,

把这个加入到类型体(type body)定义:
CONSTRUCTOR FUNCTION plch_timer_t (
   self            IN OUT plch_timer_t,
   timer_name_in   IN     VARCHAR2)
   RETURN SELF AS RESULT
IS
BEGIN
   self.timer_name := timer_name_in;
   RETURN;
END;

(D)
把这个成员函数加入到类型规格(type specification)定义:
MEMBER FUNCTION plch_timer_at (timer_name_in IN VARCHAR2)
      RETURN SELF AS RESULT

把这个加入到类型体(type body)定义:
MEMBER FUNCTION plch_timer_t (timer_name_in IN VARCHAR2)
   RETURN SELF AS RESULT
IS
BEGIN
   self.timer_name := timer_name_in;
   RETURN;
END;


论坛徽章:
24
技术图书徽章
日期:2013-08-16 14:31:52问答徽章
日期:2013-11-04 08:53:14目光如炬
日期:2013-12-23 06:00:11目光如炬
日期:2013-12-30 06:00:11明星写手
日期:2014-02-22 06:00:12马上有钱
日期:2014-03-31 14:09:05沸羊羊
日期:2015-05-20 12:42:59秀才
日期:2015-06-24 13:05:36秀才
日期:2015-07-13 09:48:14
2#
发表于 2012-5-2 09:21 | 只看该作者
偶不会,。,。。。。偶想要彩蛋蛋

使用道具 举报

回复
论坛徽章:
2
迷宫蛋
日期:2012-05-07 10:55:58奥运会纪念徽章:花样游泳
日期:2012-07-24 23:40:49
3#
发表于 2012-5-2 11:00 | 只看该作者
C

使用道具 举报

回复
论坛徽章:
171
ITPUB社区OCM联盟徽章
日期:2013-07-30 11:25:46最佳人气徽章
日期:2013-03-19 17:13:45ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30ITPUB季度 技术新星
日期:2012-05-22 15:10:11BLOG每日发帖之星
日期:2012-02-15 16:43:07生肖徽章2007版:马
日期:2012-03-07 10:13:26蓝锆石
日期:2012-02-24 10:13:15萤石
日期:2012-02-24 10:13:15海蓝宝石
日期:2012-02-24 10:13:15紫水晶
日期:2012-03-01 21:28:36
4#
发表于 2012-5-2 12:58 | 只看该作者
arron刘 发表于 2012-5-2 09:21
偶不会,。,。。。。偶想要彩蛋蛋

把newkid的帖子用心看一遍,敲一遍,就会了~

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期: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
5#
 楼主| 发表于 2012-5-3 05:09 | 只看该作者
3楼答对了,答案C.

A: ORACLE不支持私有(private)属性的定义。这个语句将会报错:
ORA-06545: PL/SQL: compilation error - compilation aborted
ORA-06550: line 4, column 23:
PLS-00103: Encountered the symbol "INTEGER" when expecting one of the following:

B:对象属性不允许指定缺省值。这个选项将会报错:
PLS-00363: expression 'START_TIME' cannot be used as an assignment target

C: 是的,你可以定义自己的构造函数,作为ORACLE自动提供的构造函数的补充,这个选项使用了正确的语法。
D: 如果你想创建一个自定义的构造函数,你必须使用CONSTRUCTOR关键字,它不能定义为类型的成员函数。

Oracle PL/SQL支持所有常见的数据类型,例如字符串,数值和日期,此外还加入了一些它自己特有的数据类型,包括记录和集合。

构造函数是你对一个对象类型的实例或者一个集合进行初始化的时候调用的方法(函数); 它的名字永远和类型名字相同。如果你未经初始化就试图使用它们,ORACLE会抛出 "ORA-06530: Reference to uninitialized composite" 错误。

当你初始化一个对象类型的实例的时候,你必须为每个属性提供一个表达式。当你初始化一个嵌套表或可变数组的时候,你可以不为数组提供任何的表达式(数组元素)。


ORACLE为每个类型定义了一个构造函数;你也可以定义自己定制的构造函数。通常这样做的目的是为了使得你不必在初始化类型的时候为每个属性提供一个表达式。

在面向对象语言中,自定义构造函数是一个很方便的功能。在ORACLE实现方法中,它们显得格外重要,因为ORACLE还不支持私有属性。这使得缺省的构造函数要求为所有的属性提供一个值,即使是那些用户永远不会直接打交道的属性(这种属性的值由对象类型自己维护)。

ORACLE提供的缺省构造函数对应每个属性都有一个参数,返回的是对象类型的一个实例。当你定义自己的构造函数时,你可以修改参数列表。通常你这样做是为了“隐藏”该类型用户不应该自己设置值的那些属性。

ORACLE不支持在对象类型中的私有属性或私有方法,这使得所有东西都是“公共”的,即使是由类型的方法来设置和操纵值的那些属性。一个自定义构造函数至少使得开发者可以不必为那些本来应该私有的属性赋值。

自定义构造函数头的语法是:

CONSTRUCTOR FUNCTION type_name (
      SELF IN OUT timer_t,
      other_parameters
)
RETURN SELF AS RESULT

使用道具 举报

回复
论坛徽章:
0
6#
发表于 2012-5-3 08:34 | 只看该作者
不会说了会被人骂的。

使用道具 举报

回复

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

本版积分规则 发表回复

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