--代码17.14 定义地址对象类型
--定义地址对象类型规范
CREATE OR REPLACE TYPE address_type
AS OBJECT
(street_addr1 VARCHAR2(25), --街道地址1
street_addr2 VARCHAR2(25), --街道地址2
city VARCHAR2(30), --城市
state VARCHAR2(20), --省份
zip_code NUMBER, --邮政编码
--成员方法,返回地址字符串
MEMBER FUNCTION toString RETURN VARCHAR2,
--MAP方法提供地址比较函数
MAP MEMBER FUNCTION mapping_function RETURN VARCHAR2
)
--定义地址对象类型体,实现成员方法与MAP函数
CREATE OR REPLACE TYPE BODY address_type
AS
MEMBER FUNCTION tostring
RETURN VARCHAR2 --将地址属性转换为字符形式显示
IS
BEGIN
IF (street_addr2 IS NOT NULL)
THEN
RETURN street_addr1
|| CHR (10)
|| street_addr2
|| CHR (10)
|| city
|| ','
|| state
|| ' '
|| zip_code;
ELSE
RETURN street_addr1 || CHR (10) || city || ',' || state || ' '
|| zip_code;
END IF;
END;
MAP MEMBER FUNCTION mapping_function --定义地址对象MAP函数的实现,返回VARCHAR2类型
RETURN VARCHAR2
IS
BEGIN
RETURN TO_CHAR (NVL (zip_code, 0), 'fm00000')
|| LPAD (NVL (city, ''), 30)
|| LPAD (NVL (street_addr1, ''), 25)
|| LPAD (NVL (street_addr2, ''), 25);
END;
END;
/
--代码17.15 定义包含其他对象类型的类型
--定义一个对象规范,该规范中包含ORDER方法
CREATE OR REPLACE TYPE employee_addr AS OBJECT (
empno NUMBER (4),
sal NUMBER (10, 2),
comm NUMBER (10, 2),
deptno NUMBER (4),
addr address_type,
MEMBER FUNCTION get_emp_info RETURN VARCHAR2
)
NOT FINAL;
--定义对象类型体,实现get_emp_info方法
CREATE OR REPLACE TYPE BODY employee_addr
AS
MEMBER FUNCTION get_emp_info
RETURN VARCHAR2 --返回员工的详细信息
IS
BEGIN
RETURN '员工'||SELF.empno||'的地址为:'||SELF.addr.toString;
END;
END;
--测试
DECLARE
o_address address_type;
o_emp employee_addr;
BEGIN
o_address:=address_type('玉兰一街','二巷','深圳','DG',523343);
o_emp:=employee_addr(7369,5000,800,20,o_address);
DBMS_OUTPUT.put_line('员工信息为'||o_emp.get_emp_info);
END;
--代码17.16 实现person_obj父对象
CREATE OR REPLACE TYPE person_obj AS OBJECT (
person_name VARCHAR (20), --人员姓名
gender VARCHAR2 (10), --人员性别
birthdate DATE, --出生日期
address VARCHAR2 (50), --家庭住址
MEMBER FUNCTION get_info
RETURN VARCHAR2 --返回员工信息
)
NOT FINAL; --人员对象可以被继承
CREATE OR REPLACE TYPE BODY person_obj --对象体
AS
MEMBER FUNCTION get_info
RETURN VARCHAR2
IS
BEGIN
RETURN '姓名:' || person_name || ',家庭住址:' || address;
END;
END;
--代码17.17 子对象employee_personobj的实现
--对象类型使用UNDER语句从person_obj中继承
CREATE OR REPLACE TYPE employee_personobj UNDER person_obj (
empno NUMBER (6),
sal NUMBER (10, 2),
job VARCHAR2 (10),
MEMBER FUNCTION get_emp_info
RETURN VARCHAR2
);
CREATE OR REPLACE TYPE BODY employee_personobj AS
MEMBER FUNCTION get_emp_info RETURN VARCHAR2 IS
BEGIN
--在对象类型体中可以直接访问在父对象中定义的属性
RETURN '员工编号:'||SELF.empno||' 员工名称:'||SELF.person_name||' 职位:'||SELF.job;
END;
END;
--测试
DECLARE
o_emp employee_personobj; --定义员工对象类型的变量
BEGIN
--使用构造函数实例化员工对象
o_emp:=employee_personobj('张小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer');
DBMS_OUTPUT.put_line(o_emp.get_info); --输出父对象的人员信息
DBMS_OUTPUT.put_line(o_emp.get_emp_info); --输出员工对象中的员工信息
END;
--代码17.18 实现对象方法重载
--对象类型使用UNDER语句从person_obj中继承
CREATE OR REPLACE TYPE employee_personobj UNDER person_obj (
empno NUMBER (6),
sal NUMBER (10, 2),
job VARCHAR2 (10),
MEMBER FUNCTION get_emp_info
RETURN VARCHAR2,
--定义重载方法
OVERRIDING MEMBER FUNCTION get_info RETURN VARCHAR2
);
CREATE OR REPLACE TYPE BODY employee_personobj AS
MEMBER FUNCTION get_emp_info RETURN VARCHAR2 IS
BEGIN
--在对象类型体中可以直接访问在父对象中定义的属性
RETURN '员工编号:'||SELF.empno||' 员工名称:'||SELF.person_name||' 职位:'||SELF.job;
END;
--实现重载方法
OVERRIDING MEMBER FUNCTION get_info RETURN VARCHAR2 AS
BEGIN
RETURN '员工编号:'||SELF.empno||' 员工名称:'||SELF.person_name||' 职位:'||SELF.job;
END;
END;
--测试
DECLARE
o_emp employee_personobj; --定义员工对象类型的变量
BEGIN
--使用构造函数实例化员工对象
o_emp:=employee_personobj('张小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer');
DBMS_OUTPUT.put_line(o_emp.get_info); --输出父对象的人员信息
END;
--17.3 管理对象表
emp_addr_table;
--定会议对象表
CREATE TABLE emp_obj_table OF employee_personobj;
CREATE TABLE emp_addr_table OF employee_addr;
set desc depth all linenum on;
desc emp_addr_table;
--在对象表中插入数据
INSERT INTO emp_obj_table VALUES('张小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer');
SELECT * FROM emp_obj_table;
INSERT INTO emp_addr_table
VALUES (7369, 5000, 800, 20,
address_type ('玉兰一街', '二巷', '深圳', 'DG', 523343));
SELECT * FROM emp_addr_table;
--将实例化的对象插入对象表
DECLARE
o_emp employee_personobj; --定义员工对象类型的变量
BEGIN
--使用构造函数实例化员工对象
o_emp:=employee_personobj('张小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer');
INSERT INTO emp_obj_table VALUES(o_emp); --插入到对象表中
END;
--在value子句中直接构造对象,再插入对象表
INSERT INTO emp_obj_table VALUES (employee_personobj('张小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer'));
--17.3.3 检索对象表
SELECT person_name,job FROM emp_obj_table;
--Value函数
SELECT VALUE(e) from emp_obj_table e;
truncate table emp_obj_table;
--单行查询
DECLARE
o_emp employee_personobj; --定义一个对象类型的变量
BEGIN
--使用SELECT INTO语句将VALUE函数返回的对象实例插入到对象类型的变量
SELECT VALUE(e) INTO o_emp FROM emp_obj_table e WHERE e.person_name='张小五';
--输出对象类型的属性值
DBMS_OUTPUT.put_line(o_emp.person_name||'的职位是:'||o_emp.job);
END;
INSERT INTO emp_obj_table VALUES (employee_personobj('张小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer'));
INSERT INTO emp_obj_table VALUES (employee_personobj('刘小艳','M',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中泰',7981,5000,'running'));
--代码17.19 使用游标和Value函数查询多行数据结果
DECLARE
o_emp employee_personobj; --定义对象类型的变量
CURSOR all_emp
IS
SELECT VALUE (e) AS emp
FROM emp_obj_table e; --定义一个游标,用来查询多行数据
BEGIN
FOR each_emp IN all_emp --使用游标FOR循环检索游标数据
LOOP
o_emp := each_emp.emp; --获取游标查询的对象实例
--输出对象实例信息
DBMS_OUTPUT.put_line (o_emp.person_name || ' 的职位是:' || o_emp.job);
END LOOP;
END;
--代码17.20 使用REF关键字创建对象表引用
CREATE TYPE address AS OBJECT ( --创建地址类型
street VARCHAR2 (35),
city VARCHAR2 (15),
state CHAR (2),
zip_code INTEGER
);
CREATE TABLE addresses OF address; --创建地址对象表
CREATE TYPE person AS OBJECT ( --创建人员对象类型
person_name VARCHAR2 (15),
birthday DATE,
home_address REF address, --使用REF关键字,指定属性为指向另一个对象表的对象
phone_number VARCHAR2 (15)
);
CREATE TABLE persons OF person; --创建人员对象表
--插入地址
INSERT INTO addresses
VALUES (address ('玉兰', '深圳', 'GD', '52334'));
INSERT INTO addresses
VALUES (address ('黄甫', '广州', 'GD', '52300'));
--插入一个人员,注意这里的home_address部分是如何插入一个ref address的。
INSERT INTO persons
VALUES (person ('王小五',
TO_DATE ('1983-01-01', 'YYYY-MM-DD'),
(SELECT REF (a)
FROM addresses a
WHERE street = '玉兰'),
'16899188'
));
--也可以用下面的过程来插入一个人员记录
DECLARE
addref REF address;
BEGIN
SELECT REF (a)
INTO addref
FROM addresses a
WHERE street = '玉兰'; --使用SELECT INTO查询一个引用对象
--使用INSERT语句向persons表中插入引用对象
INSERT INTO persons
VALUES (person ('五大狼',
TO_DATE ('1983-01-01', 'yyyy-mm-dd'),
addref,
'16899188'
));
END;
--查询某人的地址信息
SELECT person_name, DEREF (home_address)
FROM persons;
--17.3.4 更新对象列
--使用关系型数据方法更新对象
UPDATE emp_obj_table empobj
SET empobj.gender = 'M'
WHERE empobj.person_name = '张小五';
select * from emp_obj_table;
--使用实例化一个对象实例的方法更新对象
UPDATE emp_obj_table empobj
SET empobj=employee_personobj('李小七','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'众泰',7981,7000,'Testing')
WHERE person_name='张小五';
--代码17.22 在Where子句中使用对象类型
DECLARE
emp_ref REF employee_personobj; --定义引用对象类型
BEGIN
SELECT REF(e1)
INTO emp_ref
FROM emp_obj_table e1
WHERE person_name = '刘小艳'; --从对象表中获取对刘小艳的对象引用
UPDATE emp_obj_table emp_obj
SET emp_obj =employee_personobj('何小凤',
'F',TO_DATE ('1985-08-01', 'YYYY-MM-DD'),
'本甜',7981, 7000, 'developer')
WHERE REF (emp_obj) = emp_ref;
END;
DECLARE
addr address;
BEGIN
SELECT DEREF(home_address) INTO addr FROM persons WHERE person_name='王小五';
addr.street:='五一';
UPDATE address SET street=addr.street WHERE zip_code='523330';
END;
--17.3.5 删除对象表
--普通方法
DELETE FROM emp_obj_table WHERE person_name='李小七';
--再where子句中删除
DECLARE
emp_ref REF employee_personobj; --定义引用对象类型
BEGIN
SELECT REF(e1)
INTO emp_ref
FROM emp_obj_table e1
WHERE person_name = '何小凤'; --从对象表中获取对刘小艳的对象引用
DELETE FROM emp_obj_table emp_obj
WHERE REF (emp_obj) = emp_ref;
END; --使用DELETE语句删除emp_obj_table表中刘小艳的记录
SELECT * FROM emp;
--代码17.23 定义对象类型
--定义与关系表emp相匹配列的对象类型
CREATE OR REPLACE TYPE emp_tbl_obj AS OBJECT (
empno NUMBER (6),
ename VARCHAR2(10),
job VARCHAR2(18),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
depno NUMBER(2),
MEMBER FUNCTION get_emp_info
RETURN VARCHAR2
)
INSTANTIABLE NOT FINAL;
/
--定义对象类型体
CREATE OR REPLACE TYPE BODY emp_tbl_obj AS
MEMBER FUNCTION get_emp_info RETURN VARCHAR2 IS
BEGIN
--在对象类型体中可以直接访问在父对象中定义的属性
RETURN '员工编号:'||SELF.empno||' 员工名称:'||SELF.ename||' 职位:'||SELF.job;
END;
END;
/
--创建emp_view对象表
CREATE VIEW emp_view
OF emp_tbl_obj
WITH OBJECT IDENTIFIER (empno)
AS
SELECT e.empno, e.ename, e.job, e.mgr, e.hiredate, e.sal, e.comm, e.deptno
FROM emp e;
/
--代码17.25 使用对象类型的视图
DECLARE
o_emp emp_tbl_obj; --定义对象类型的变量
BEGIN
--查询对象类型
SELECT VALUE(e) INTO o_emp FROM emp_view e WHERE empno=7369;
--输出对象类型的属性
DBMS_OUTPUT.put_line('员工'||o_emp.ename||' 的薪资为:'||o_emp.sal);
DBMS_OUTPUT.put_line(o_emp.get_emp_info); --调用对象类型的成员方法
END;