對象
?
??? 在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
?