服务器 频道

Oracle 中的OOP概念

  【IT168 服务器学院】对象类型:

  优点:

  1)  更容易与Java, C++编写的对象应用程序交互

  2)  获取便捷。一次对象类型请求就可以从多个关系表中获取信息,通过一次网络往复即可返回

  语法:

  CREATE [OR REPLACE] TYPE type_name

  {{AS| IS } OBJECT | UNDER super_type}

  {

         attribute_name datatype[,attribute_name datatype]… ---成员变量

         [{MAP | ORDER} MEMBER function_name,]   ---排序函数

         [{FINAL | NOT FINAL} MEMBER function_name,]  ---可否继承的成员函数

         [{INSTANTIABLE | NOT INSTANTIABLE } MEMBER function_name,]       ---可否实例化的成员函数

         [{MEMBER | STATIC } function_name,]     ---静态、非静态成员函数

  }

  [{FINAL | NOT FINAL}]     ---对象可否继承

  [{INSTANTIABLE | NOT INSTANTIABLE }]    ---对象可否实例化

  /

  对象类型的主体部分(即函数的实现部分,可选的):

  CREATE [OR REPLACE]

  TYPE BODY type_name {AS| IS }                   

         [{MAP | ORDER} MEMBER function_body,]   ---排序函数

         [{MEMBER | STATIC } function_name,]     ---静态、非静态成员函数

  END;

  /

  例如:

  create or replace

  type person as object(

         first_name varchar2(100),

         last_name varchar2(100))

  /

  属性类型可以是任何oracle 数据类型(包括自定义),除了如下:

  LONG和LONG RAW

  NCHAR、NCLOB 、NVARCHAR2

  ROWID、UROWID

  PL/SQL的特定类型:%TYPE  %ROWTYPE

  查看:

  Desc person

  构造函数:

  set serveroutput on

  declare

         l_person person

  begin

         l_person := person(‘Donny’,’Chen’);

         dbms_output.putline(l_person.first_name);

  end;

  /

  构造函数要接受对象类型的所有属性作为参数。因为这些参数没有默认值,即使是null,也要提供。

  举例:

  表中的对象类型:

  对象类型可以作为数据库中的列,所以称为列对象

  create table person_table

  (

         name person,

         age number)

  /

  set desc depth all

  desc person_table

  set desc depth 1

  插入数据:

  insert into person_table

         values(person(‘Donny’,’Chen’),30);

  declare

         l_person person

  begin

         l_person := person(‘Hua’,’Li’);

         insert into person_table values(l_person,33);

  end;

  /

  查询数据:

  select * from person_table

  访问对象类型的各个属性:

  select p.name.first_name

         from person_table p

  /

  为避免名称解析问题,要求查询对象类型的属性的时候,使用表别名。否则报错,举例:

  对象中的对象(合成):

  create or replace

  type employee as object(

         name person,

         empno number,

         hiredate date)

  /

  修改和删除对象:

  9i之前,当建立的对象类型,以及依赖于此类型的对象或表之后,就无法再修改此对象类型了(增加删除属性和成员函数)。唯一的办法是撤销所有以来,即删除依赖于此类型的对象或表。

  9i新特性,可以修改被以来的对象类型,成为类型演化。有两种方法:

  INVALIDATE 和 CASCADE

  INVALIDATE比如:

  desc person_table

  改变person类型,增加新属性ssn

  alter type person

         add attribute ssn varchar2(11) INVALIDATE;

  desc person   (bug可能需要新开一个session)

  INVALIDATE选项使的所有依赖于person类型的对象和表标记为INVALID,比如:

  Desc person_table

  需要手工验证person_table:

  alter table person_table upgrade including data;

  desc person_table

  upgrade including data表示根据新类型,物理上更新现有的数据的结构,ssn 置为null。

  也可以upgrade not including data,不更新原有数据的结构。Dml访问person实例数据的时候再更新。

  Select * from person_table

  CASCADE比如:

  alter type person

  add attribute dob date

  cascade not including table data

  /

  不用手工验证依赖此对象类型的表,由数据库自动验证。

  Desc person

  Desc person_table

  因为not including table data,没有更新原有数据:

  select * from person_table

  删除类型:

  force

  方法:

  即对象中的过程和函数,3种类型:

  STATIC: 只能够在对象类型上调用,不专属于某个实例。

  MEMBER: 专属于某个特定的实例

  CONSTRUCTOR: 构造函数

  create or replace

  type employee as object(

         name person,

         empno number,

         hiredate date,

         sal number,

         commission number,

         member function total_compensation return number,

         static function new(p_empno number,

                              p_person person) return employee)

  /

  desc employee

  在类型主体实现这两个方法:

  create or replace

  type body employee as

         member function total_compensation return number is

         begin

                return nvl(self.sal,0) + nvl(self.commission, 0);

         end;

         static function new(p_empno number,

                              p_person person) return employee is

         begin

                return employee(p_person,p_empno,sysdate,10000,null);

         end;

  end;

  /

  比较抽象数据类型的数据:

  declare

         l_employee1 employee;

         l_employee2 employee;

  begin

         l_employee1 :=employee.new(12345,null);

         l_employee2 :=employee.new(67890,null);

         if l_employee1= l_employee2 then

                dbms_output.line_put(“They are equal”);

         end if;

  end;

  /

  使用map指定具体比较哪些属性:

  create or replace

  type employee as object(

         name person,

         empno number,

         hiredate date,

         sal number,

         commission number,

         map member function convert return number)

  /

  create or replace

  type body employee as

         map member function convert return number is

         begin

                return self.empno;

         end;

  end;

  /

  再比较:

  declare

         l_employee1 employee;

         l_employee2 employee;

  begin

         l_employee1 :=employee.new(12345,null);

         l_employee2 :=employee.new(67890,null);

         if l_employee1= l_employee2 then

                dbms_output.line_put(“They are equal”);

         end if;

         if l_employee1> l_employee2 then

                dbms_output.line_put(“employee1 is greater”);

         end if;

         if l_employee1< l_employee2 then

                dbms_output.line_put(“employee2 is greater”);

         end if;

  end;

  /

  Order 方法:

  create or replace

  type employee as object(

         name person,

         empno number,

         hiredate date,

         sal number,

         commission number,

         order member function match(p_employee employee) return integer)

  /

  create or replace

  type body employee as

         order member function match(p_employee employee) return integer is

         begin

                if self.empno> p_employee.empno then

         return 1;

                elseif self.empno< p_employee.empno then

                return -1;

         else

                return 0;

         end if;

         end;

  end;

  /

  继承:

  FINAL / NOT FINAL
  对象默认FINAL,表示不可以被继承;

  MEMBER方法也能指定是否FINAL,表示能否在子类中对他进行覆写。默认NOT FINAL

  Create or replace type super_type as object(

         N number,

         Final member procedure cannot_override

  )

  not final

  /

0
相关文章