对象
在Oracle中把对象作为一种数据类型object,不但可以包含基本的数据类型、集合,还可以为其定义函数和过程作为其方法。
创建格式如下:
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
)
);
注意:不能在数据类型中定义以下类型:
1.LONG、LONG RAW
2.ROWID
3.PL/SQL特定类型(BINARY_INTEGER、BOOLEAN、%TYPE、%ROWTYPE)
4.程序包中自定义的数据类型
构造函数
使用之前创建的对象建立构造函数:
declare
person_one person;
begin
person_one:=person(
'
张三
'
,
'
男
'
,
date
'2008-10-11'
,
'
杭州
'
);
dbms_output.put_line(person_one.name);
end
;
说明:先创建了一个person类型的局部变量,再为该变量创建了一个实例。
在实例化中用到的person是系统的构造函数,可以对person类型变量进行赋值,该构造函数在对象创建时由系统自动创建,与对象的名称相同。
注:创建对象实例时必须提供全部参数,否则报错。
引用对象类型
可以创建实例化的对象之后,将该对象插入到堆表中。
1、例如创建含有person类型数据的表:
create
table
t_person(
person_col person,
emp_id
number
,
dep_id
number
);
2、直接插入数据:
insert
into
t_person
values
(person(
'
张三
'
,
'
男
'
,
date
'2008-10-11'
,
'
杭州
'
),
12345
,
11
);
commit
;
3、也可以在PL/SQL中先创建保存实例的变量,再进行插入:
declare
person_one person;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
insert
into
t_person
values
(person_one,
12345
,
11
);
commit
;
end
;
4、之后可进行查询数值:
SQL
>
select
*
from
t_person;
PERSON_COL(
NAME
, SEX, BIRTHDATE, PLACE) EMP_ID DEP_ID
--------------------------------------------- --------- ---------
PERSON(
'
张三
'
,
'
男
'
,
'11-OCT-08'
,
'
杭州
'
)
12345
11
PERSON(
'
李四
'
,
'
男
'
,
'20-OCT-08'
,
'
上海
'
)
12345
11
5、若需要查询对象中的某个变量,则必须在最前面加上表名:
SQL
>
select
a.person_col.NAME
from
t_person a;
PERSON_COL.NAME
----------------
张三
李四
注:当在某表中加入对象后,对象在table被drop之前不能被drop。
方法
对象类型内的function和procedure都是方法,可以重载。Oracle的对象类型共有5种方法:实例方法、类方法、构造函数、映射方法、排序方法。
1、实例方法和类方法
实例方法是必须创建实例后才可以调用的方法,而类方法可以在创建实例前调用。实例方法用member声明,类方法用static
创建type和type body:
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
),
member
procedure
chang_name(
name
varchar2
),
static
function
new
(v_name
varchar2
,v_sex
varchar2
)
return
person
);
create
or
replace
type
body
person
is
member
procedure
chang_name(
name
varchar2
)
is
begin
self.name:=
name
;
end
chang_name;
static
function
new
(v_name
varchar2
,v_sex
varchar2
)
return
person
is
begin
return
(person(v_name,v_sex,
null
,
null
));
end
new
;
end
;
在过程中调用两种不同类型的方法:
declare
person_one person;
person_two person;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);--创建实例
person_one.chang_name(
'
王五
'
);
dbms_output.put_line(person_one.name);
person_two:=person.new(
'
小张
'
,
'
女
'
);--可直接调用
dbms_output.put_line(person_two.name);
end
;
2、映射方法
由于将对象作为字段时,对象中包含很多参数须发进行比较,此时可以为对象创建映射方法。
在创建映射方法后,如果用到where 或 order by 以及 <>= 等比较关系时,自动调用映射方法。
注:映射方法不带参数,且只能有一个。
创建type和type body:
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
),
map
member
function
compare
return
date
);
create
or
replace
type
body
person
is
map
member
function
compare
return
date
is
begin
return
self.birthdate;
end
compare;
end
;
调用映射方法进行比较:
declare
person_one person;
person_two person;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
person_two:=person(
'
小张
'
,
'
女
'
,
date
'2008-10-11'
,
'
杭州
'
);
if
person_one > person_two
then
dbms_output.put_line(person_one.name||
'
比
'
||person_two.name||
'
大
'
);
elsif
person_one < person_two
then
dbms_output.put_line(person_two.name||
'
比
'
||person_one.name||
'
大
'
);
else
dbms_output.put_line(
'
一样大
'
);
end
if
;
end
;
3、排序方法
排序方法主要为了简化比较对象大小的值,相当于sign
举例说明,创建type和type body:
create
or
replace
type
person
as
object
(
NAME
varchar2
(
10
),
SEX
char
(
2
),
BIRTHDATE
date
,
PLACE
varchar2
(
100
),
order
member
function
match(p_person person)
return
integer
);
create
or
replace
type
body
person
is
order
member
function
match(p_person person)
return
integer
is
begin
if
self.birthdate > p_person.birthdate
then
return
1
;
elsif
self.birthdate < p_person.birthdate
then
return
-
1
;
else
return
0
;
end
if
;
end
match;
end
;
调用排序函数:
declare
person_one person;
person_two person;
k
int
;
begin
person_one:=person(
'
李四
'
,
'
男
'
,
date
'2008-10-20'
,
'
上海
'
);
person_two:=person(
'
小张
'
,
'
女
'
,
date
'2008-10-11'
,
'
杭州
'
);
k:=person_one.match(person_two);
--one
调用
match
去和
two
比较
dbms_output.put_line(k);
end
;
注:当排序大量对象时,适合用MAP,当反复比较时,适合用ORDER