Oracle 中的OOP概念 对象类型,可变数组,嵌套表,对象表,对象视图 对象类型:
优点: 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 /
|