您的位置:首页 > 数据库 > Oracle

【转】Oracle Object type 对象类型详解

2016-02-18 10:40 796 查看
Oracle Object type 对象类型

一、概述

Oracle对象类型是Oracle面向对象程序设计的体现,它封装了数据结构和用于操纵这些数据结构的过程和函数。

1、对象类型的组成

对象类型由两部分组成——对象类型头和对象类型体。

对象类型头用于定义对象的公用属性和方法;对象类型体用于实现对象类型头所定义的公用方法。

2、对象类型属性

定义对象类型最少要包含一个属性,最多包含1000个属性。定义时必须提供属性名和数据类型,但不能指定默认值和not null。

数据类型不能包括long、long raw、rowid、urowid和PL/SQL特有类型(boolean\%type\%rowtype\ref curdor等)

3、对象类型的方法

定义对象类型可以包含也可以不包含方法,可以定义构造方法、member方法、static方法、map方法和order方法。

1)、构造方法

用于初始化对象并返回对象实例。构造方法是与对象类型同名的函数,默认的构造方法参数是对象类型的所有属性。

9i前只能使用系统默认的构造方法、9i后可自定义构造函数,自定义必须使用constructor function关键字

2)、member方法

用于访问对象实例的数据。当使用member方法时,可以使用内置参数self访问当前对象实例。

当定义member方法时,无论是否定义self参数,它都会被作为第一个参数传递给member方法。

但如果要定义参数self,那么其类型必须要使用当前对象类型。member方法只能由对象实例调用,而不能由对象类型调用。

3)、static方法

用于访问对象类型,可以在对象类型上执行全局操作,而不需要访问特定对象实例的数据,因此static方法引用self参数。

static方法只能由对象类型调用,不能由对象实例调用(和member相反)。

4)、map方法

对象类型不同于标量类型可以直接比较,为了按照特定规则排序对象实例的数据,可以定义map方法,但只能有一个,与order互斥。

map方法将对象实例映射成标量数值来比较。

5)、order方法

map可以在对多个对象实例之间排序,而order只能比较2个实例的大小。定义对象类型时最多只能定义一个order方法,

而且map和order方法不能同时定义。使用原则是可不用则均不用,比较2个对象则用order,对个对象则用map。

4、对象表

对象表是指至少包含一个对象类型列的表。分为行对象表和列对象表。

行对象表是指直接基于对象类型所建立的表;列对象表则是只包含一个或多个列的对象表。

5、REF数据类型

ref是指向行对象的逻辑指针,是Oracle的一种内置数据类型。建表时通过使用REF引用行对象,可以使不同表共享相同对象。

例如:create table department(dno number(2),dname varchar2(10),emp ref employee_type)

二、对象类型的基本应用

1、概述

基本应用也属于最常规、最简单的应用,讲述如何建立和使用独立的并且与其他对象类型无关的对象类型。

包括语法、建立带方法和不带方法的对象类型。

2、语法

create or replace type type_name as object (

v_name1 datatype[,v_name2 datatype,...],

[member|static method1 spec,member|static method2 spec,...]);

create or replace type body type_name as

member|static method1 body;

member|static method1 body;...

其中,type_name是对象类型的名称,v_name是属性名称,datatype是属性数据类型,method是方法的名称,body是PL/SQL的方法实现代码。

如果定义对象类型头时没有定义方法,则不需要建立对象类型体。

3、建立和使用不包含任何方法的对象类型

--建立对象类型

create or replace type person_typ1 as object(name varchar2(10),gender varchar2(2),birthdate date);

1)、对于行对象表

--建立行对象表

create table persong_tab1 of person_typ1;

--插入

begin

insert into person_tab1 values('马丽','女','11-1月-76');--不用构造方法

insert into person_tab1 values(person_typ1('王鸣','男','12-2月-76'));--用构造方法

end;

--查询,必须使用value函数取得行数据

declare

person person_typ1;

begin

select value(p) into person from person_tab1 p where p.name='&name';

dbms_output.put_line(person.gender||','||person.birthdate);

end;

--更新

begin

update person_tab1 p set b.birthdate='11-2月-76' where p.name='马丽';

end;

--删除

begin

delete from person_tab1 p where p.name='马丽';

end;

2)、对于列对象表

--建立列对象表

create table employee_tab1(eno number(6),person person_typ1,sal number(6.2),job varchar2(10));

--插入,必须使用构造方法(默认构造方法)

begin

insert into employee_tab1(eno,sal,job,person) values(1,2000,'高级电工',person_typ1('王鸣','男'.'01-8月-76'));

end;

--查询

declare

employee person_typ1;

salary number(6,2);

begin

select person,sal into employee,salary from employee_tab1 where eno=&no;

dbms_output.put_line(employee.name||','||salary);

end;

--更新

begin

update employee_tab1 p set p.person.birthdate='&newdate' where p.person.name='&name';

end;

--删除

begin

delete from employee_tab1 p where p.person.name='王鸣';

end;

4、建立和使用包含方法的对象类型

--建立对象类型头

create or replace type person_typ2 as object

(

name varchar2(10),

gender varchar2(2),

birthdate date,

address varchar2(100),

regdate date,

member procedure change_address(new_addr varchar2),--member方法

member function get_info return varchar2,--member方法

static function getdate return date,--static方法

map member function getage return varchar2,--map方法

order member function compare(p person_typ2) return int,--order方法

constructor person typ2(name varchar2) return self as result,

constructor person typ2(name varchar2,gender varchar2) return self as result

);

--建立对象类型体

create or replace type body person_typ2 is

member procedure change_address(new_addr varchar2) is

begin

address := new_addr; --member方法体现之处,直接访问修改对象实例的数据address

end;

member function get_info return varchar2 is

v_info varchar2(100);

begin

v_info := name || ',' || birthdate || ',' || regdate;

return v_info;

end;

static function gerdate return date is

begin

return sysdate;

end;

map member function getage return varchar2 is

begin

return
trunc((sysdate-birthdate)/365);--比较的依据是按照时间

end;

order member function compare(p person_typ2) return int is

begin

case

when
birthdate>p.birthdate then return 1;

when
birthdate=p.birthdate then return 0;

when
birthdate>p.birthdate then return -1;

end case;

end;

constructor function person_typ2(name varchar2) return self as result is

begin

self.name:=name;

self.gender:='女';

self.birthdate:=sysdate;

return;

end;

constructor function person_typ2(name varchar2,gender varchar2) return self as result is

begin

self.name:=name;

self.gender:=gender;

self.birthdate:=sysdate;

return;

end;

end;

--建立列对象表

create table employee_tab2(eno number(6),person person_typ2,sal number(6,2),job varchar2(10));

--插入

insert into employee_tab2(eno,sal,job,person) values(1,1500,'图书管理员',

person_typ2('马丽','女','11-1月-75','呼和浩特11号',person_typ2.getdate()));--由对象类型调用的全局方法getdate(static方法)

insert into employee_tab2(eno,sal,job,person) values(2,2000,'高级焊工',

person_typ2('王鸣','男','11-5月-75','呼和浩特21号',person_typ2.getdate()));

insert into employee_tab2(eno,sal,job,person) values(3,3000,'高级工程师',

person_typ2('李奇','男','11-5月-70','呼和浩特31号',person_typ2.getdate()));

insert into employee_tab2(eno,sal,job,person) values(3,3000,'高级工程师',person_typ2('怪兽');--自定义构造方法

insert into employee_tab2(eno,sal,job,person) values(3,3000,'高级工程师',person_typ2('怪兽','男');

--调用

declare

v_person person_typ2;

type person_table_type is table of person_typ2;

person_table person_table_type;

begin

select person into v_person from employee_tab2 where eno = &&no;

v_person.change_address('呼和浩特12号');

update employee_tab2 set person = v_person where eno = &no;

dbms_output.put_line(v_person.get_info);

--map,取表中前2条数据来对比

select person bulk collect into person_table from employee_tab2;

if person_table(1).getage()>person_table(2).getage() then

dbms_output.put_line(person_table(1).name||'比'||person_table(2).name||'大');

else

dbms_output.put_line(person_table(2).name||'不比'||person_table(1).name||'大');

end if;

--compare

if person_table(1).compare(person_table(2))=1 then

dbms_output.put_line(person_table(1).name||'比'||person_table(2).name||'大');

else

dbms_output.put_line(person_table(2).name||'不比'||person_table(1).name||'大');

end if;

end;

三、对象类型的高级应用

1、概述

高级应用简述与其他对象类型具有关联关系的对象类型。包括对象类型的嵌套、参照对象类型、对象类型的继承。

2、对象类型的嵌套

1)、建立对象类型addr_typ7

create or replace type addr_typ7 as object(

state varchar2(20),city varchar2(20),street varchar2(50),zipcode(6),

member function get_addr return varchar2);

create or replace type body addr_typ7 as

member function get_addr return varchar2 is

begin

return
state||city||street;

end;

end;

2)、建立对象类型person_typ7,嵌套addr_typ7对象类型

create or replace type person_typ7 as object(

name varchar2(10),gender varchar2(2),birthdate date,

address addr_typ7,member function get_info return varchar2);

create or replace type body person_typ7 as

member function get_info return varchar2 is

begin

return
'姓名:'||name||',家庭住址'||address.get_addr();

end;

end;

3)、建立列对象表employee_tab7

create table employee_tab7(eno number(6),person person_typ7,sal number(6,2),job varchar2(10));

4)、插入

insert into employee_tab7(eno,sal,job,person) values

(1,1500,'图书管理员',person_typ7('马丽','女','01-11月-76',addr_typ7('内蒙古自治区','呼和浩特市','呼伦北路22号','010010')));

insert into employee_tab7(eno,sal,job,person) values

(2,2000,'高级钳工',person_typ7('王鸣','男','11-12月-75',addr_typ7('内蒙古自治区','呼和浩特市','呼伦北路50号','010010')));

5)、更新

declare

v_person person_typ7;

begin

select person into v_person from employee_tab7
where eno=1;

v_person.address.street:='北恒东街11号';

update employee_tab7 set person=v_person
where eno=1;

end;

6)、查询

declare

v_person_typ7;

begin

select person into v_person from employee_tab7
where eno=1;

dbms_output.put_line(v_person.get_info);

end;

6)、删除

begin

delete from employ33_tab7 where eno=1;

end;

3、参照对象类型

1)、概述

参照对象类型是指在建立对象表时使用REF定义表列,REF实际是指向行对象表数据的指针。

通过使用REF定义表列,可以使得一个对象表引用另一个对象表(行对象表)的数据。

2)、建立对象类型person_typ8

create or replace type person_typ8 as object(

name varchar2(10),gender varchar2(2),birthdate date,address varchar2(100),

member function get_info return varchar2

);

create or replace type body person_typ8 as

member function get_info return varchar2 is

begin

return name||',0'||address;

end;

end;

3)、建立行对象表person_tab8

create table person_tab8 of person_typ8;

insert into person_tab8 values('马丽','女','11-1月-75','呼和浩特11号');

insert into person_tab8 values('王鸣','男','11-5月-75','呼和浩特21号');

4)、建立列对象表employee_tab8

说明:employee_tab8表直接引用person_tab8表的数据。

create table employee_tab8(

eno number(6),person ref person_typ8,sal number(6,2),job varchar2(10));

5)、插入

说明:因为employee_tab8的定义使用ref引用了person_tab8,所以插入需要引用该表数据。,使用函数REF

begin

insert into employee_tab8 select 1,ref(a),2000,'图书管理员' from person_tab8 a where a.name='马丽';

insert into employee_tab8 select 2,ref(a),2000,'高级钳工' from person_tab8 a where a.name='王鸣';

end;

6)、查询

说明:取ref对象列数据,必须使用deref。

declare

v_person person_typ8;

begin

select deref(person) into v_person from employee_tab8 where eno=1;

dbms_output.put_line(v_person.get_into);

end;

7)、更新

declare

v_person person_typ8;

begin

select deref(perosn) into v_person from employee_tab8 where eno=1;

v_person.address:='呼和浩特市神马路';

update person_tab8 set address=v_person.address where name=v_person.name;

end;

8)、删除

begin

delete from employee_tab8 where eno=1;

end;

4、对象类型的继承

1)、概述

9i新增,一个对象类型继承另一个对象类型。定义需要被继承的父类时需要指定not final,否则默认final,表示对象类型不能被继承。

2)、建立对象类型person_typ9

create or replace type person_typ9 as object(

name varchar2(10),gender varchar2(2),birthdate date,address varchar2(100),

member function get_info return varchar2

) not final;

create or replace type body person_typ8 as

member function get_info return varchar2 is

begin

return name||',0'||address;

end;

end;

3)、建立子对象类型

create or replace type employee_typ9 under person_typ9(

eno number(6),sal number(6,2),job varchar2(10),

member function get_other return varchar2);

create or replace type body employee_typ9 as

member function get_other return varchar2 is

begin

return name||','||sal;

end;

end;

4)、建立行对象表

create table employee_tab9 of employee_typ9;

insert into person_tab8 values('马丽','女','11-1月-75','呼和浩特11号',1,1500,'图书管理员');

insert into person_tab8 values('王鸣','男','11-5月-75','呼和浩特21号',2,2000,'高级钳工');

5)、查询

declare

v_employee employee_typ9;

begin

select value(a) into v_employee from
employee_tab9 a where a.eno=1;

dbms_output.put_line(v_employee.get_info||','||v_employee.get_other);

end;

四、维护对象类型

1、显示对象类型信息

select type_name,attributes,final from user_types;

2、增删对象类型的属性

alter type person_typ1 add attribute address varchar2(50) cascade;

alter type person_typ1 drop attribute birthdate cascade;

--cascade级联更新依赖对象类型的对象类型和对象表。

3、增删对象类型的方法

alter type person_typ1 add member function get info return varchar2 cascade;

create or replace type body person_typ1 as

member function get_info return varchar2 is

begin

return name||','||address;

end;

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: