PL/SQL Challenge 每周一题:2021-11-27 对象实例的比较

[复制链接]
查看11 | 回复0 | 2008-9-15 01:28:12 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。
每两周的优胜者可获得itpub奖励的技术图书一本。
以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808
原始出处:
https://devgym.oracle.com/
作者:Kim Berg Hansen
运行环境:SQLPLUS, SERVEROUTPUT已打开, 最低版本要求:11.2
注:本题给出答案时候要求给予简要说明才能得到奖品
我想要创建一个名为QZ_NAME_T的对象类型,包含属性FIRST_NAME 和 LAST_NAME。
我想要能够把它当作一个表的列来使用,在查询输出中能够以这样一种方式来对这个对象列排序,使得先按LAST_NAME然后按FIRST_NAME排序。
哪些选项能够成功创建一个对象类型不出错,使得对象创建之后,这个代码能够成功执行不出错,并且产生所示的输出:
create table qz_people (
idinteger primary key
, nameqz_name_t
);
insert into qz_people values (
42, qz_name_t(first_name => 'Esmerelda' , last_name => 'Weatherwax')
);
insert into qz_people values (
43, qz_name_t(first_name => 'Sacharissa', last_name => 'Cripslock' )
);
insert into qz_people values (
44, qz_name_t(first_name => 'Galder', last_name => 'Weatherwax')
);
commit;
select p.name.last_name, p.name.first_name
from qz_people p
order by p.name;
NAME.LAST_NAME NAME.FIRST_NAME
-------------------- --------------------
Cripslock
Sacharissa
Weatherwax Esmerelda
Weatherwax Galder
(A)
create or replace type qz_name_t as object (
last_name varchar2(20)
, first_namevarchar2(20)
);
/
(B)
create or replace type qz_name_t as object (
first_namevarchar2(20)
, last_name varchar2(20)
, order member function full_name_order return varchar2
);
/
create or replace type body qz_name_t as
order member function full_name_order return varchar2
is
begin
return 'last_name, first_name';
end full_name_order;
end;
/
(C)
create or replace type qz_name_t as object (
first_namevarchar2(20)
, last_name varchar2(20)
, order member function full_name_order (p_name qz_name_t) return integer
);
/
create or replace type body qz_name_t as
order member function full_name_order (p_name qz_name_t) return integer
is
begin
return
case

when last_name = p_name.last_name and first_name = p_name.first_name

then 0

when last_name ), 但是当我们执行测试查询的时候报错了:
ORA-22950: cannot ORDER objects without MAP or ORDER method.
B:
如同前一选项的错误信息所示,我们需要在类型中创建MAP 或者ORDER方法。
但是ORDER成员方法并不是要返回一个"ORDER BY"风格的列清单。这是无效的语法,所以CREATE会报错:
PLS-00521: ORDER methods must be declared with 1 (one) parameter in addition to (optional) SELF.
C:
和前一选项不同的是,这是ORDER成员方法的正确用法例子,它接收另外一个对象实例作为参数,然后和当前实例(隐式的SELF参数)进行比较。
假如当前对象实例比传入的对象实例小,返回值必须是一个负数(例如-1),如果当前对象实例比传入的对象实例大则是正数(例如1),如果两个对象实例相等则为零。
数据库会重复调用这个函数来决定哪些对象比其他对象更大或者更小,为集合中的对象进行排序。
D:
前一选项没有在ORDER成员方法的参数列表中指定SELF,在CASE语句中也没有使用SELF。这个选项在两个地方都明确指定了SELF,但是结果和依赖于隐式SELF用法的前一选项完全相同,这和前一选项一样能够工作。
E:
ORDER成员方法是为了比较两个对象实例来找出哪一个更大。
另外的方法是使用MAP成员方法,它不接受对象参数,而是返回一个标量值,将其作为对象值的“映射”,从而使得数据库能够在返回的标量值上面执行普通的排序。
在这个例子中,我们可以用 "Weatherwax, Esmerelda"的格式创建一个带有全名的字符串,数据库可以在这个字符串值上轻易地高效地排序。
如果你的情况是有可能将对象值映射为一个标量值,那么这通常比一个ORDER成员方法更为高效----不仅因为它只需每行只被调用一次,也因为它使得优化器能够使用标量值排序的所有选项(例如,用散列排序算法,这在ORDER成员方法是不能做到的)
回复

使用道具 举报

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

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行