Oracle PL/SQL高级编程(第二弹:管理对象表)

定义对象表

对象表就像普通的表一样,只是存储的是对象类型,该表的每一个字段与对象的一个属性相对应。对象表的每一条记录存储一个对象类型的实例。语法如下:
CREATE TALE table_name OF object_type;

对象表基于的是系统定义的构造函数,而不是用户定义的构造函数,所以在向对象表插入数据时,必须要在构造函数中提供匹配的所有的属性值。

创建的对象表一旦引用了特定的对象类型,就不能使用DROP TYPE删除对象类型。

插入对象表

以上一篇文章中创建的employee_personobj为例,我们先来创建一个对象表:

CREATE TABLE emp_obj_table OF employee_personobj;

然后插入数据:

INSERT INTO emp_obj_table VALUES('张小五','F',
                             TO_DATE('1983-01-01','YYYY-MM-DD'),
                             '中信',7981,5000,'Programmer');

也可以这样插入数据:

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和REF函数这两种检索方法。

VALUE函数

在查询语句中使用VALUE函数将返回存储在对象表中的对象实例。
比如查询单行:

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;       

查询多行:

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;

REF函数

REF和VALUE的区别在于REF返回的是指向对象实际位置的一个指针,而VALUE是把对象副本从一个子程序传递到另一个子程序。

看代码,我们先来使用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;     --创建人员对象表

然后向addresses对象表中插入数据:

--插入地址
INSERT INTO addresses
     VALUES (address ('玉兰', '深圳', 'GD', '52334'));
INSERT INTO addresses
     VALUES (address ('黄甫', '广州', 'GD', '52300'));

接下来向persons对象表插入数据,我们将使用 REF函数,通过REF函数返回的对addressed表中特定对象的引用,插入到persons表中:

--插入一个人员,注意这里的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语句进行查询,引用类型的列将会是一串数字码,而且引用类型的对象无法直接访问其属性。需要使用DEREF函数,才可以查询到引用类型所指向的地址类型的值,如:
SELECT person_name, DEREF (home_address) FROM persons;

更新对象表

可以像更新普通表一样更新对象表:

UPDATE emp_obj_table empobj
   SET empobj.gender = 'M'
 WHERE empobj.person_name = '张小五';

也可以直接更新对象表中的一个对象实例:

UPDATE emp_obj_table empobj
  SET empobj=employee_personobj('李小七','F',
                             TO_DATE('1983-01-01','YYYY-MM-DD'),
                             '众泰',7981,7000,'Testing')
  WHERE person_name='张小五';      

还可以在WHERE条件中使用REF函数来获取对象的标识符(对象标识符是对象表中为了唯一标识一条记录而定义的一串数字值),来更新数据:

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;              --使用UPDATE语句更新emp_obj_table表中刘小艳的记录
END;

如果对象表的属性列表中包含了引用类型,而我们需要修改其列所引用的数据,就必须修改相应的 行对象。例如在persons表中,hone_address字段是一个指向address对象类型的引用,因此如果要UPDATE这个包含引用类型的表,可以这么做:

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;

删除对象表

如:
DELETE FROM emp_obj_table WHERE person_name='张小五';
也可以这样:

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;              --使用DELETE语句删除emp_obj_table表中刘小艳的记录
END;

创建对象列

除了将整个对象作为表中的列来存储的对象表之外,还可以为关系对中的某一列的属性指定为对象类型,这种表称为带对象列的关系表。
这个比较简单,这里就不举例。

使用对象视图

对象视图可以让我们使用面向对象的特性来操作关系型数据结构,如果想将已存在的关系型的数据更改为使用OOP(面向对象)的操作方式,使用对象视图非常有用。为了创建一个对象视图,必须首先创建一个与底层数据表的列具有相匹配属性的对象类型。

举个例子,要以对象的方式操作emp表,可以先基于emp表的表列定义一个对象类型,下面我们来定义个emp_tbl_obj,用来匹配对emp表的操作:

--定义与关系表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),
deptno   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;
/

接下来就可以创建一个基于该对象类型的视图。在创建对象视图时,必须要确定要使用的OID(对象标识符)。对象标识符是用来唯一标识一行对象的一个字符串,通过OID可以保证对对象实例引用的唯一性。OID仅在对象表和对象视图上被创建,一旦一个OID被赋给了一个对象,那么将永远属于那个对象。通常情况下,Oracle会自动产生OID值,不需要手工产生,但在定义对象视图时,可以覆盖系统产生OID的机制,更改为使用对象表的额主键来替代。
下面来创建基于emp_tbl_obj的对象类型的emp表的对象视图:

--创建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;

在创建了这个对象视图以后,就可以用前面介绍的对象操作语法来操作对象了:

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;

猜你喜欢

转载自blog.csdn.net/lianjiww/article/details/81605991