继承
1、创建父类型
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
),
member
function
get_name
return
varchar2
)
not
final
;
--
必须注明,默认为
final
create
or
replace
type
body
person
is
member
function
get_name
return
varchar2
is
begin
return
self.name;
end
get_name;
end
;
2、创建person的子类
create
or
replace
type
employee
under
person
(
emp_id
varchar2
(
10
),
dep_id
varchar2
(
10
),
job
varchar2
(
20
)
);
3、应用父类和子类
declare
person_one person;
employee_one employee;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
employee_one:=employee(
'
小张
'
,
'
女
'
,
date
'2008-10-11'
,
'
杭州
'
,
'123456'
,
null
,
null
);
dbms_output.put_line(person_one.get_name);
dbms_output.put_line(employee_one.get_name);
end
;
注:与其他OOP一样,子类继承父类的参数及函数,但注意子类的参数顺序,都在父类之后顺序排列。
4、父类可引用子类实例:
declare
person_one person;
employee_one employee;
begin
person_one:=employee(
'
小张
'
,
'
女
'
,
date
'2008-10-11'
,
'
杭州
'
,
'123456'
,
null
,
null
);
--
正确!
employee_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
--
错误,子类不可引用父类实例!
dbms_output.put_line(person_one.name);
--
正确!
dbms_output.put_line(person_one.emp_id);
--
错误,父类忽略子类参数!
end
;
重写
1、建立父类
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
),
member
procedure
show_msg
)
not
final
;
create
or
replace
type
body
person
is
member
function
show_msg
return
varchar2
is
begin
dbms_output.put_line(
name
||
'/'
||sex||
'/'
||birthdate);
end
show_msg;
end
;
2、创建子类
create
or
replace
type
employee
under
person
(
emp_id
varchar2
(
10
),
dep_id
varchar2
(
10
),
job
varchar2
(
20
),
overriding
member
procedure
show_msg--关键字overriding
);
create
or
replace
type
body
employee
is
overriding
member
procedure
show_msg
is
begin
dbms_output.put_line(emp_id||
'/'
||dep_id||
'/'
||job);
end
show_msg;
end
;
3、重写方法的调用
declare
person_one person;
employee_one employee;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
employee_one:=employee(
'
小张
'
,
'
女
'
,
date
'2008-10-11'
,
'
杭州
'
,
'123456'
,
'11'
,
'22'
);
person_one.show_msg;
--
李四
/
男
/20-OCT-08
employee_one.show_msg;
--123456/11/22
end
;
4、类多态
declare
person_one person;
person_two person;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
person_two:=employee(
'
小张
'
,
'
女
'
,
date
'2008-10-11'
,
'
杭州
'
,
'123456'
,
'11'
,
'22'
);
person_one.show_msg;
--
李四
/
男
/20-OCT-08
person_two.show_msg;
--123456/11/22
end
;
对象表
要区分对象表和将对象作为字段的表。
对象表是基于对象类型创建的表,对象表的每一行都代表一个对象。
1、创建对象表
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
)
)
;
create
table
t_person
of
person;
--
注意格式!
2、插入数据(2种方法)
insert
into
t_person
values
(
'
张三
'
,
'
男
'
,
date
'2008-10-11'
,
'
杭州
'
);
--
直接插入
insert
into
t_person
values
(person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
));
--
插入实例
注:其实第一种方法是由系统隐式创建了对象实例,然后插入
3、查询数据(2种方法)
SQL
>
select
*
from
t_person;
NAME
SEX BIRTHDATE PLACE
-------- ---- --------- --------
张三
男
11
-OCT-
08
杭州
李四
男
20
-OCT-
08
上海
SQL
>
select
value
(a)
from
t_person a;
VALUE
(A)(
NAME
, SEX, BIRTHDATE, PLACE)
----------------------------------------
PERSON(
'
张三
'
,
'
男
'
,
'11-OCT-08'
,
'
杭州
'
)
PERSON(
'
李四
'
,
'
男
'
,
'20-OCT-08'
,
'
上海
'
)
对象表外键
1、对象表之间外键通过REF指针实现创建,首先创建外部表
create
table
t_person_f(
emp_id
integer
,
emp_msg
ref
person
scope
is
t_person
);
注1:定义字段emp_msg为person对象类型的ref指针
注2:scope表示实例来源,只能从表t_person中获取
2、向外部表中插入数据
insert
into
t_person_f
select
123
,
ref
(a)
from
t_person a
where
a.name=
'
张三
'
;
注:必须使用select语句通过ref获取实例
3、查询外部表,通过deref来解析
SQL
>
select
*
from
t_person_f;
--
无法查询真实信息
EMP_ID EMP_MSG
---------- ----------------------------------------------
123
0000220208
C
5A
9B48F328840D7BF1B44EA41B24A11F8
SQL
>
select
emp_id,
deref
(emp_msg)
from
t_person_f;
EMP_ID
DEREF
(EMP_MSG)(
NAME
, SEX, BIRTHDATE, PLACE)
--------- -------------------------------------------------
123
PERSON(
'
张三
'
,
'
男
'
,
'11-OCT-08'
,
'
杭州
'
)
4、外键管理
对象表要求外键引用的行必须存在,而ref则没有这个限制,删除时会指向空值,解析为NULL。
delete
from
t_person
where
name
=
'
张三
'
;
--
删除对象
SQL > select emp_id,deref(emp_msg) from t_person_f;
EMP_ID DEREF(EMP_MSG)(NAME, SEX, BIRTHDATE, PLACE)
--------- -------------------------------------------------
123
可以使用dangling关键字,查询所有被悬空的ref
SQL
>
select
emp_id
from
t_person_f
where
emp_msg
is
dangling
;
EMP_ID
----------
123