源码-PL/SQL从入门到精通-第十七章-面向对象编程-Part 2


--代码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; 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值