------------------------抽象数据类型----------- --创建地址类型,一定要加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、可变数组更新时必须更新整个可变数组,而嵌套表更新时可以只更新嵌套表中的部分记录 出处:http://www.cnblogs.com/hoojo/archive/2011/05/03/2035407.html
|