-
简介
- 说明:Oracle属于面向对象的数据库,所以在Oracle中也允许用户基于类的结构进行数据表的创建,同时采用类的关系进行表中数据的维护
- 示例1:定义要使用的类结构
-- 删除emp_object,否则dept_object无法重新建立 DROP TYPE emp_object ; -- 定义部门类 CREATE OR REPLACE TYPE dept_object AS OBJECT ( atri_deptno NUMBER(2) , -- 部门编号 atri_dname VARCHAR2(14) , -- 部门名称 atri_loc VARCHAR2(13) , -- 部门位置 -- 取得对象信息 MEMBER FUNCTION tostring RETURN VARCHAR2 ) NOT FINAL ; / -- 定义Person类规范 CREATE OR REPLACE TYPE person_object AS OBJECT ( atri_pid NUMBER , -- 人员编号 atri_name VARCHAR2(10) , -- 人员姓名 atri_sex VARCHAR2(10) , -- 人员性别 NOT INSTANTIABLE MEMBER FUNCTION tostring RETURN VARCHAR2 , -- 定义抽象方法 -- 实现对象排序 NOT INSTANTIABLE MAP MEMBER FUNCTION compare RETURN NUMBER ) NOT FINAL NOT INSTANTIABLE ; -- 此处必须使用NOT INSTANTIABLE声明类 / -- 定义Emp类规范,此类为Person子类 CREATE OR REPLACE TYPE emp_object UNDER person_object ( atri_job VARCHAR2(9) , -- 雇员职位 atri_sal NUMBER(7,2) , -- 雇员工资 atri_comm NUMBER(7,2) , -- 雇员佣金 atri_dept dept_object , -- 雇员部门 -- 此函数名称与父类函数名称一样,所以此处为函数的覆写 OVERRIDING MEMBER FUNCTION tostring RETURN VARCHAR2 , -- 实现对象排序 OVERRIDING MAP MEMBER FUNCTION compare RETURN NUMBER ) ; / -- 定义dept_object类体 CREATE OR REPLACE TYPE BODY dept_object AS MEMBER FUNCTION tostring RETURN VARCHAR2 AS BEGIN RETURN '部门编号:' || SELF.atri_deptno || ',名称:' || SELF.atri_dname || ',位置:' || SELF.atri_loc ; END ; END ; / -- 定义emp_object类体 CREATE OR REPLACE TYPE BODY emp_object AS OVERRIDING MEMBER FUNCTION tostring RETURN VARCHAR2 AS BEGIN RETURN '人员编号:' || SELF.atri_pid || ',姓名:' || SELF.atri_name || ',性别:' || SELF.atri_sex || '职位:' || SELF.atri_job || ',工资:' || SELF.atri_sal || ',佣金:' || SELF.atri_comm ; END ; OVERRIDING MAP MEMBER FUNCTION compare RETURN NUMBER AS BEGIN RETURN SELF.atri_sal + SELF.atri_comm ; END ; END ; / |
此程序定义了3个类规范,由于person_oobject属于抽象类,所以只定义了两个类体; |
|
-
创建对象表
- 当用户定义完一个类之后,就可以依据此类中的属性结构创建指定的对象表,语法如下:
CREATE TABLE 表名称 OF 类; |
在创建对象表时,如果对象表中存在了继承的操作关系,那么也会将继承而来的相应属性自动变为数据表中的列 |
-
示例1:创建一个对象表
CREATE TABLE emp_object_tab OF emp_object ; |
- 查看emp_object_tab数据表结构
DESC emp_object_tab ; |
- 通过此时的查询结果可以发现,atri_dept这个嵌套类型依然会以对象的形式存在,同时emp_object_tab表中包含了person_object和emp_object的所有属性;
-
维护对象表数据
- 对象表建立完成之后对表中的数据同样分为4类:增加,修改,删除,查询
-
数据增加,使用INSERT语句:
-
示例1:增加数据,但是不增加部门属性数据
-
INSERT INTO emp_object_tab(atri_pid,atri_name,atri_sex,atri_job,atri_sal,atri_comm) VALUES (10,'hey','男','办事员',3500,100); |
-
示例2:增加数据,同时使用嵌套类型
INSERT INTO emp_object_tab(atri_pid,atri_name,atri_sex,atri_job,atri_sal,atri_comm,atri_dept) VALUES (20,'yy','男','技术员',5500,200, dept_object(10,'开发部','北京')); |
-
数据查询:
-
示例1:查询emp_object_tab表中的全部数据
-
SELECT * FROM emp_object_tab ; |
-
在进行对象表数据查询时,还可以利用VALUE()或REF()函数进行数据的查询
- VALUE函数:利用此函数可将对象表中的数据转化为对象返回,这样可以利用查询后的对象信息进行排序
- REF()函数:VALUE()函数可将嵌套的对象信息直接保存在对象表中,这种做法有时会造成数据的冗余。例如,一个部门会存在多个雇员,每当增加雇员数据时,都需要重复保存部门信息。所以在Oracle中也提供了数据的地址指向,如图:
-
数据更新,需要考虑对象类型的操作列:
-
示例1:更新emp_object_tab对象表(此表不使用REF引用)中的部门信息
-
UPDATE emp_object_tab SET atri_job='经理' , atri_dept=dept_object(30,'魔乐','加拿大') WHERE atri_pid=10 ; |
接上例:查询emp_object_tab对象表中修改后的数据
SELECT * FROM emp_object_tab WHERE atri_pid=10 ; |
-
示例2:更新emp_object_ref_tab对象表(此表使用REF引用)中的部门信息
UPDATE emp_object_ref_tab SET atri_dept=( SELECT REF(d) FROM dept_object_ref_tab d WHERE atri_deptno=30) WHERE atri_pid=3020 ; |
-
接上例:查询emp_object_ref_tab对象表中修改后的数据
SELECT atri_pid,atri_name,atri_sex,atri_job,atri_sal,atri_comm, DEREF(atri_dept) dept FROM emp_object_ref_tab WHERE atri_pid=3020 ; |
-
示例3:除了使用更新对象列之外,还可以取出相应的对象信息设置数据的更新条件
- 更新emp_object_ref_tab对象表中所有10部门雇员信息
UPDATE emp_object_ref_tab SET atri_name='王月清',atri_sal=6000 WHERE atri_dept=(SELECT REF(d) FROM dept_object_ref_tab d WHERE atri_deptno=10) ; |
-
查询emp_object_ref_tab数据表的数据
SELECT atri_pid,atri_name,atri_sex,atri_job,atri_sal,atri_comm, DEREF(atri_dept) dept FROM emp_object_ref_tab ; |
-
删除数据,可以按照普通字段或者对象字段进行操作:
-
示例1:删除emp_object_ref_tab表中10部门的雇员信息
-
DELETE FROM emp_object_ref_tab WHERE atri_dept=(SELECT REF(d) FROM dept_object_ref_tab d WHERE atri_deptno=10) ; |
-
接上例:查询emp_object_ref_tab数据表的数据
SELECT atri_pid,atri_name,atri_sex,atri_job,atri_sal,atri_comm, DEREF(atri_dept) dept FROM emp_object_ref_tab ; |