ORACLE中的OOP
--1:创建自定义抽象数据类型:
create or replace type baseinfo as object (name varchar2(20),sex varchar2(4)); --2:使用抽象数据类型:
create table person
(pid int primary key,info baseinfo);
--3:查看抽象数据类型
----设置定义抽象数据类型的层次,类似JAVA中创建包允许的包层次 --------connect as sys 来设置这个参数
--------例;可以设置成可以查看的层次为10, set describe depth 10 set describe depth all ----查询
Set describe depth all --设置描述一个对象的层次 desc baseinfo --查询对象类型数据字典
select type_name,attr_name ,length from user_type_attrs
where type_name='BASEINFO'; --user_type_attrs是ORACLE定义的一个视图
----查看用户自定义的所有类型: select type_name from user_types; --4 向抽象数据类型中插入数据
--构造函数:类名(类型中定义的参数)如:baseinfo(属性一,属性二) insert into person values(1001,baseinfo('rose','f'));
--5 查询包含抽象数据类型的表
select * from person
--6 查询抽象数据类型的字段值
select a.info.name,a.info.sex from person a select a.info from person a --7 更新抽象数据类型 update person p
set p.info.name='jack' --8 删除数据 delete from person; delete from person p where p.info.name='jack'
--9 删除抽象数据类型:如果不使用force关键字则只有在其他对象不依赖该对象的情况下才可以删除
drop type baseinfo [FORCE] ----使用force 关键字删除抽象数据类型 drop type baseinfo FORCE
----可以使用下面的方法来查询依赖情况;
SELECT name, type, referenced_name, referenced_type FROM USER_DEPENDENCIES --User_dependencies --All_ dependencies --Dba_ dependencies
--10 创建包含属性和方法的抽象数据类型创建和使用 create or replace type info as object
(age number,
member function getage return number,
static function new(newage number) return info); --创建类型主体
create or replace type body info as member function getage return number is
begin
return self.age; end;
static function new(newage number) return info is begin
return info(newage); end;
end;
--使用包含属性和方法的抽象数据类型 declare myinfo info;
begin
myinfo :=info.new(35);
dbms_output.put_line('中文myinfo.age is : '||myinfo.age); end;
--11 final 和not final可以继承否?ORACLE默认final alter type baseinfo final; alter type baseinfo not final
--12 抽象数据类型的使用—继承(not final) ----创建基类
create or replace type person as object (
age number, tel varchar2(13),
member function getage return number, member function gettel return varchar2 ) not final; ----创建基类型主体
create type body person as
member function getage return number is begin
return self.age; end;
member function gettel return varchar2 is begin
return self.tel; end; end;
----/*创建子类型*/
create type rose under person (
id number, work_tel varchar2(20),
overriding member function gettel return varchar2, member function gethometel return varchar2 )
not final;
----创建子类型主体
create type body rose as
overriding member function gettel return varchar2 is Begin
return self.work_tel; end;
member function gethometel return varchar2 is Begin
return self.tel; end; end;
----基类方法调用
declare
qiuxiang rose; begin
qiuxiang:=rose(100,'120',10001,'83084478');
dbms_output.put_line('秋香的办公室work_tel电话号码是:'||qiuxiang.gettel()); dbms_output.put_line('秋香的家庭电话号码是:'||qiuxiang.gethometel()); dbms_output.put_line('秋香的年龄是:'||qiuxiang.getage()); end;
--13 抽象数据类型在表中的使用 ----创建表
create table newperson(p person);
--此时不可以重建此类型,因为对此类型的相关依赖没有删除,即它的子类型依赖于它,直接使用以前的person类型 create or replace type person as object (
age number,
tel varchar2(13),
member function getage return number, member function gettel return varchar2 )
not final;
----数据录入,rose(age,tel,id,work_tel)参数父类优先 insert into newperson values(person(103,'119'));
insert into newperson values(rose(104,'83084478',152628770325251,'010-68730166'));
insert into newperson values(rose(105,'80000000',15262111111111,'010-68730166'));
--java中的casting:如果要把一个派生类对象赋值给基类对象这个称为上溯造型(upper casting)。
--如果要把基类对象赋值给派生类对象就需要强制类型转换,这称为下溯造型。 --下溯造型有一些危险,要安全的进行下溯造型有一个前题,基类对象必须是从派生类对象中上溯过来的。 ----数据查询
select x.p.age from newperson x;
----子类的信息如何查询?使用treat函数强制把基类转换成子类 select treat(x.p as rose).id from newperson x; ----查询表中所有属于子类型的列 ----使用is of关键字来判断对象的类型
select treat(x.p as rose).tel from newperson x where p is of (rose);
--14 Instantiable和not Instantiable ----interface:没有构造函数或不提供方法的实现 not instantialle
----对象类型定义为not Instantiable 则不能建立该类型的实例。因此,不需要构造函数。
----方法定义为not Instantiable时,该方法不能由基类实现,必须由子类覆盖并且实现
----/*基类定义*/
create type animal as object (
age number,
not instantiable member function call return number
)
not instantiable not final; ----/*子类定义*/
create type xiaoqiang under animal (
overriding member function call return number )
;
----/*创建子类类型主体*/
create type body xiaoqiang as
overriding member function call return number is begin
dbms_output.put_line('this is xiaoqiang!'); return 0; end; end;
----/*测试实现*/ declare
tangbohu xiaoqiang; res number;
begin
tangbohu := xiaoqiang(10); res := tangbohu.call(); end;
--15 可变数组 ----创建
create type name as varray(4) of varchar2(10); create type sex as varray(2) of varchar2(6); ----使用
create table person(pid int ,pname name,psex sex); ----向可变数组中插入记录 begin
insert into person values
(1001, name('a', 'rose', 'tom', 'jack'), sex('m', 'f'));
insert into person values
(1002, name('aaaa', 'bbbb', 'cccc', 'ddddd'), sex('f'));
insert into person values (1003, name('a', 'rose', 'tom'), sex('m')); end;
select * from table(select pname from person where pid=1001 and rownum<2) array;
select * from table(select pname from person where pid=1002 and rownum=1) array;
----从可变数组中选择数据
select * from person --显示不全面,但在sql plus中可以 select p.pid,p.pname,p.psex from person p
----关于2月24日课程作业:关于可变数组array[i]的查询
create or replace type ptype as object (id number(4),name varchar2(20),sex varchar2(6));
create type personvarry as varray(4) of ptype;
create table person(pid number(4),pinfo personvarry);
insert into person values(1001,personvarry(ptype(001,'aaa','m'),ptype(002,'bbb','f')));
insert into person values(1002,personvarry(ptype(001,'ccc','m'),ptype(002,'ddd','f')));
select * from person;
select pinfo from person
select * from table(select pinfo from person p where p.pid = 1001);
select a.name from table(select pinfo from person p where p.pid = 1001) a where a.id=001;
select a.name from table(select pinfo from person p where p.pid = 1001) a where a.id=002;
--16 嵌套表:表中之表,首先定义对象类型,然后根据对象类型定义表类型 ----创建对象类型
create type provider as object (
pid number, pname varchar2(10), ptel varchar2(10)
) ;
----创建provider抽象数据类型的表类型 create type pro as table of provider; ----创建包含pro表类型的表 create table goods (gid int primary key , gname varchar2(10), provi pro)
nested table provi store as g_provi;
----插入数据,可以使用table关键字强制类型转换 insert into goods values(1001, 'mp3',
pro(provider(2001,'tel','110'), provider(2002,'tel','120')));
insert into table (select g.provi from goods g where g.gid=1001) values(2003,'sun','120');
--可以看到除了基础类型字段外其他无法查询到,此时在sqlplus下可以看到,在pl/sql devloper下无法看到 select * from goods
select g.provi from goods g where g.gid=1001;
select * from table(select g.provi from goods g where g.gid=1001); select p.pname from table(select provi from goods where gid=1001) p; ----更新嵌套表
update table (select g.provi from goods g where g.gid=1001) p set value(p)=provider(2001,'tcl','119')
where p.pid=2001; /*更新指定供应商的信息*/ ----删除
delete from table (select g.provi from goods g where g.gid=1001) p where p.pid=2001; /*指定产品除去一个供应商*/
--17 对象表,行对象:表中的每一行都代表一个对象
----定义地址对象类型
create type address as object (pcode number,address varchar2(30)); ----创建对象表,并插入数据
create table address_table of address; ----使用ref将新建的表与对象表中的数据关联 create table emp_loc(empno number, loc ref address scope is address_table);
----录入数据
insert into emp_loc select 1001,ref(a) from address_table a where a.pcode=710061;
----ref()函数可以返回指向对象表中对象实例的指针。 commit; -- 如果不提交则看不到指针地址 select ref(a) from obj_info a; --返回的是指针 ----通过对象表更新对象数据。不写例子了
Deref()函数使用ref数据类型作为自己的参数,返回对应的ref对象的实例。 select empno,deref(loc) from emp_loc; //在sql plus中执行 select l.eid,deref(l.loc) from emploc l; 创建对象视图 ------创建类型
create type type1 as object(tid number(5),tname varchar2(10)); ------创建对象表
create table test of type1; ------创建对象表视图
create or replace view vw_test of type1 with object oid(tid) as select * from test;