Oracle笔记 十二、PL/SQL 面向对象oop编程

————————抽象数据类型———–
–创建地址类型,一定要加as object,还可以在类型中加过程或方法
create or replace type address as object (
province varchar2(10), –省份属性
city varchar2(10) –市属性
) not final; –not final表示该类型可以有子类型

–定义一个子类型
–under address说明这个类型继承至address类型
create or replace type detailAddress under address (
street varchar2(20) –街道属性 第3个成员
);

–创建员工信息表,最后一列是detailAddress类型
drop table empInfo
create table empInfo (
eName varchar2(20) , –员工姓名
eSex char(2), –性别
eAge int, –年龄
eAddress detailAddress –员工地址
);

–增加数据,只能用构造方法
insert into empInfo values(‘aaa’, ‘男’, 28, detailAddress(‘湖北’, ‘襄樊’, ‘八一路’));
insert into empInfo values(‘bbb’, ‘男’, 26, detailAddress(‘湖北’, ‘武汉’, ‘永清街’));
insert into empInfo values(‘ccc’, ‘女’, 29, detailAddress(‘湖北’, ‘武汉’, ‘光谷’));

–查询
select from empInfo;
select
from empInfo where eSex = ‘男’;
select * from empInfo e where e.eAddress.city = ‘武汉’; –如果查询条件包含属性必须用表的别名
–更新有2种方式:
–第一种方式:整体更新
update empInfo e set e.eAddress = detailAddress(‘湖北’, ‘武汉’, ‘武昌’) where e.eName = ‘ccc’;
–第二种方式:只更新抽象类型的某一列
update empInfo e set e.eAddress.city = ‘武汉’ where e.eName = ‘ccc’;

–删除
delete from empInfo e where e.eAddress.city = ‘武汉’;

–为抽象数据类型的属性建立索引
create index idxemp on empInfo(eAddress.city);
–删除
drop table empInfo;
drop type address force; –强制删除抽象类型

——————————-抽象数据类型结束———————-

——————对象表,表中的每一行就是一个对象———————–
–创建抽象数据类型person,并作为基类型
create or replace type person as object (
pName varchar2(20), –姓名
pSex char(2), –性别
pAge int –年龄
) not final;

–创建子类型student,继承person
–后面不要加as object
create or replace type student under person (
stuId int
);

–创建对象表stuInfo
create table stuInfo of student;
–为对象表创建主键约束
alter table stuInfo add constraint pk_stuInfo primary key(stuId);
–插入数据,当普通表插入
insert into stuInfo values(‘aaa’, ‘男’, 29, 1001);
–插入数据,用构造方法
insert into stuInfo values(student(‘bbb’, ‘男’, 26, 1002));
insert into stuInfo values(student(‘ccc’, ‘女’, 29, 1003));
–查询,当普通表用
select * from stuInfo where stuId = 1002;

–更新和删除都用普通的sql语句即可
update stuInfo set pAge = 29 where pName = ‘ccc’;
delete from stuInfo where stuId = 1001;
rollback;

–ref(表别名)函数用来返回对象的OID,也就是对象标识符,对象表也有rowid
select ref(s) from stuInfo s;
select rowid, ref(s) OIDS from stuInfo s;

–创建学生分数表,注意外键
create table stuScore (
stu ref student, –stu这一列的值必须出现在stuInfo表中,且stu这一列存的对象的OID而不是对象本身
score int –分数
);
–向分数表插入数据,只能用select,不能用普通的values
–错误的做法:insert into stuscore values(select ref(s) from stuInfo where stuId = 1001, 90)
–正确的做法:
insert into stuscore select ref(s), 90 from stuInfo s where stuId = 1001;
insert into stuscore select ref(s), 80 from stuInfo s; –插入3行数据
insert into stuscore select ref(s), 70 from stuInfo s where stuId = 1003;

–查询
select * from stuScore;
–deref(列名)函数可以把OID还原为对象,主键列显示有问题
select deref(s.stu), score from stuScore s where s.stu.stuId = 1001;

–修改,以下2个都可以
update stuScore set score=100 where stu = (select ref(s) from stuInfo s where stuId = 1001);
update stuScore s set score = 99 where s.stu.stuId = 1001;
–删除,以下3个都可以
delete from stuScore where stu = (select ref(s) from stuInfo s where stuId = 1001);
delete from stuScore s where s.stu.stuId = 1001;
delete from stuScore where stuId = 1001;
———————————-对象表结束———————-

———————————-对象视图———————–
–对象视图的作用:把已经存在的关系表转换为对象表来使用,原表没有变
–首先要创建一个和原表一样的类型
–然后创建视图
create table aaa
(a int);
create type aaaa as object
(a int);
create or replace view view_stu of aaaa with object oid(a)
as
select * from aaa;

select * from view_stu;
–增删改查都和对象表一样
——————————-对象视图结束———————–

——————————–抽象类型,包含过程和方法————-
create or replace type ADDRESS as object (
province varchar2(10), –省份
city varchar2(10), –市,后面的,不能少
member function get_pro return varchar2, –函数,后面接,而不是;
member function get_city return varchar2,
member procedure set_pro(pro varchar2), –过程
member procedure set_city(cy varchar2)
);

create or replace type body ADDRESS–后面不能加 as object
as –后面不能加begin

member function get_pro return varchar2
is
begin
return province;
end get_pro;

member function get_city return varchar2
is
begin
return city;
end;

member procedure set_pro(pro varchar2)
is
begin
province := pro;
end;
member procedure set_city(cy varchar2)
is
begin
city := cy;
end;
end;

–测试上面的成员函数和过程
declare
addr address;
begin
addr := address(‘湖北’, ‘武汉’);
dbms_output.put_line(addr.get_city);
end;

–drop table stuInfo;
create table stuInfo (
stuId int primary key,
addr address
);

declare
addr address;
begin
addr := address(‘湖北’, ‘武汉’);
insert into stuInfo values(1, addr);
addr.set_city(‘郑州’);
addr.set_pro(‘河南’);
insert into stuInfo values(2, addr);
end;

select * from stuInfo;
–删除类型
drop type address force;
————————–抽象类型,包含过程和方法 结束————-
—————————-可变数组——————————
–就是一个可以存储多个值的有最大长度的数组,数组的成员可以是任意类型
–建立一个可变数组类型,长度是10,存放的数据类型是number(4)
create or replace type arrType as varray(10) of number(4);

create or replace type scoreType as object (
subName varchar2(10),
score int
);
–创建一个长度为10的可变数组,存放数据类型是scorType
create or replace type arrScoreType as varray(10) of scoreType;
–创建学生信息表
–drop table stuInfo;
create table stuInfo (
stuId int primary key,
score arrScoreType –可变数组,最多10个成员
);
–插入数据,用可变数组的构造函数
insert into stuInfo values(1, arrScoreType(
scoreType(‘sql’, 50), scoreType(‘C#’, 80), scoreType(‘java’, 90)));
insert into stuInfo values(2, arrScoreType(
scoreType(‘sql’, 60), scoreType(‘C#’, 85), scoreType(‘java’, 95), scoreType(‘html’, 60)));
insert into stuInfo values(3, arrScoreType(
scoreType(‘sql’, 70), scoreType(‘java’, 93)));
–查询
select from stuInfo; –查询结果是集合
–如何才能查询出可变数组里的数据呢?思路是:用table函数把集合转化为表,然后再从这个表查询数据
select
from table(select s.score from stuInfo s where s.stuId = 2);
–table函数里面只能是一个可变数组

select s.stuId, t.* from stuInfo s,
table(select score from stuInfo where stuId = s.stuId) t
where s.stuId = 2;
–更新,整个可变数组一起更新,不能只更新数组的某个元素
update stuInfo set score = arrScoreType(
scoreType(‘sql’, 50), scoreType(‘C#’, 80)) where stuId = 1;
–删除,按主键删除
—————————–可变数组结束———————————
drop type scoreType force;
drop type arrScoreType force;
drop table stuInfo;

—————————–嵌套表—————————
–创建抽象类型
create or replace type scoreType as object (
subName varchar2(10),
score int
);
–创建嵌套表类型
create or replace type nestTable is table of scoreType;
–创建包含嵌套表的学生信息表
create table stuInfo (
stuId int,
score nestTable –其实存的是引用,实际数据存在abc表中
) nested table score store as abc;
–nested table score store as abc意思是:stuInfo这个表中的score这一列是嵌套表类型,嵌套表实际是存在abc这个表中

–增删和可变数组一样
insert into stuInfo values(3, nestTable(
scoreType(‘sql’, 70), scoreType(‘java’, 93)));
–查询,思路:把嵌套表先查出来,然后把嵌套表和stuInfo进行联合查询
select from table(select ss.score from stuInfo ss where stuId = 3);
select s.stuId, t.
from stuInfo s, table(select ss.score from stuInfo ss where stuId = s.stuId) t
where s.stuId = 3;
–更新
update table(select ss.score from stuInfo ss where stuId=3) t
set t.score = 80 where t.subName = ‘sql’;
–删除
delete from table(select ss.score from stuInfo ss where stuId = 3) t
where t.subname=’sql’;

—-可变数组和嵌套表的异同—————-
相同点:
1、都是抽象类型
2、都可以作为表中某列的数据类型(record和快表是不能作为列的数据类型的)
不同点:
1、可变数组本身就存放在原表中,而嵌套表存放在另外的表中
2、可变数组有大小限制,而嵌套表没有
3、可变数组更新时必须更新整个可变数组,而嵌套表更新时可以只更新嵌套表中的部分记录
版权维护转载hoojo博客的。