说明:目前只是最常用的定义语法,以后再慢慢更新了。定义一个对象类型包含两部分,定义类型和定义类型体。CREATE TYPE语句定义类型的名称,属性,方法。CREATE TYPE BODY语句实现方法。
-------------------定义类型---------------------------
CREATE [OR REPLACE] TYPE [schema.]type_name
[调用者权限定义]
类型层次
[
(属性声明|元素声明[,,,])
]
[[NOT] FINAL] (注:用于类型)
[[NOT] INSTANTIABLE] (注:用于类型)
;
各部分说明如下:
OR REPLACE
如果类型存在的话就改变其定义,此子句的好处是在创建之前不需要首先删除已存在的类型。当然由于对象之间的依赖性,使用此子句可能会出错。
[schema.]type_name
对象类型名称。如果忽略schema,则在当前架构内创建类型。
调用权限定义(此定义同时应用于其对应的类型体)
调用权限定义指定三方面的内容:
(1)方法的执行权限。
(2)其所在的架构。
(3)Oracle使用此定义来解析方法中查询、DML操作、动态SQL语句所引用的外部名称。
有两种调用权限定义:
AUTHID CURRENT_USER(调用者权利类型)
方法的执行权限由调用者决定。同时,在调用者的架构内解析外部名称。
AUTHID DEFINER(定义者权利类型)
方法的执行权限由定义者决定。同时,在定义者的架构内解析外部名称。
使用限制条件:
(1)只有在定义对象类型时才能使用此子句,不能用于嵌套表和数组。
(2)可以在子类上使用此子句,但是子类的调用权限定义必须与超类上的调用权限定义相同。
(3)如果超类使用定义者权利类型,则子类和超类必须在同一架构内。
类型层次
IS|AS OBJECT
创建一个顶级(根)对象类型。
UNDER [schema.]supertype_name
继承某个超类。
[NOT] FINAL(注:用于类型)
指定是否可创建子类。
[NOT] INSTANTIABLE(注:用于类型)
指定是否可实例化(默认为可实例化)。当为NOT INSTANTIABLE时,不能定义任何构造函数。如果类型包含虚方法,或者不包含任何属性(继承的或是定义的),则必须使用NOT INSTANTIABLE。
属性声明
attr_name datatype
-----------------下面部分为元素声明------------------------
语法如下:
[继承性子句] {子程序定义|构造函数定义|比较方法定义}
继承性子句
继承性子句是元素声明的一部分,用于说明超类与子类的关系。语法如下:
{[NOT] {OVERRIDING | FINAL | INSTANTIABLE}},,,
[NOT] OVERRIDING
此子句仅对成员方法有效(默认为NOT OVERRIDING)。指定覆盖超类的方法,如果要重新定义父类的方法,就必须使用OVERRIDING。注意,此子句对静态方法和SQLJ对象类型无效。
[NOT] FINAL
此子句指示方法是否能被子类覆盖。默认为NOT FINAL,即可被覆盖。
[NOT] INSTANTIABLE
此子句指示方法是否为虚方法,即不提供方法实现。默认为INSTANTIABLE,即提供方法实现。包含虚方法的类是不可实例化的。
构造函数定义
此子句用于定义自定义的构造函数。除抽象类外,每个类都包含一个隐式的构造函数,其参数顺序与类型定义中的属性声明一致。可以定义多个构造函数,只要这些构造函数的参数在数量、顺序或数据类型上不相同即可。语法如下:
[FINAL] [ INSTANTIABLE] CONSTRUCTOR FUNCTION datatype
[([SELF IN OUT datatype,] {parameter datatype},,,)]
RETURN SELF AS RESULT [IS | AS 调用约定]
说明:
(1)自定义的构造函数总是FINAL和INSTANTIABLE,所以可以省略FINAL和INSTANTIABLE。
(2)FUNCTION后面的datatype还不清楚什么用处,一般类型定义的话就是为正在定义的类型的type_name。
(3)用户定义的构造函数总是SELF IN OUT,所以可以省略。
(4) RETURN SELF AS RESULT表示构造函数返回的值的类型与隐式参数SELF的运行时类型相同。
比较方法定义
只能在顶层类中定义一个MAP方法或是一个ORDER方法,子类可以覆盖超类的MAP方法,但不能覆盖ORDER方法。
如果类未定义比较方法的话,则只能进行相等性比较,此时不能对对象进行排序,仅当两个同一类型定义的两个对象的所有对应的属性均相等时,才认为这两个对象相当。
MAP方法一般用于大量对象实例的排序或是散列连接。MAP方法返回系统预定义的标量值(DATE,NUMBER,VARCHAR2,或是ANSI SQL类型如CHARACTER或REAL)。当涉及到排序的查询(如ORDER BY,DISTINCT,或是UNION子句)引用了类型名称,Oracle可以使用MAP方法进行并行查询。
ORDER方法的效率不如MAP方法好,它直接比较两个对象,并返回一个整型,大于0,等于0,小于0分别表示大于,等于和小于。ORDER方法也可以用于排序,但是不能用于散列连接。如果定义了ORDER方法,Oracle在比较时会自动调用此方法。ORDER方法的效率虽不如MAP高,但是它主要用于表示复杂的比较。
两个方法都可以被Oracle调用,所以一般只定义其中一个。
MAP方法定义:
MAP MEMBER FUNCTION func_name RETURN {DATE | NUMBER | VARCHAR2 | CHARACTER | REAL}
ORDER方法定义:
ORDER MEMBER FUNCTION func_name (parameter type_name) RETURN INTEGER (注:type_name必须为同一类型)
子程序定义
子程序定义包含过程定义和函数定义。其一般语法如下:
MEMBER | STATIC {过程定义 | 函数定义}
MEMBER
表示定义成员方法。
STATIC
表示定义静态方法。
过程定义语法:
PROCEDURE proc_name [({parameter datatype},,,)] [IS | AS {调用约定}]
函数定义语法:
FUNCTION func_name [({parameter datatype},,,)] RETURN datatype [IS | AS {调用约定}]
-------------------定义类型体---------------------------
任何在创建类型时未指定调用约定的方法,在类型体中都要定义实现体。
CREATE [OR REPLACE] TYPE BODY [schema.]type_name IS|AS
{子程序实现|构造函数实现|比较方法实现},,,
END;
说明如下:
(1)定义类型体不要忘了用END;结束。
(2)实现体要么是PL/SQL块,要么是调用约定。
(3)对于构造函数,一定要用RETURN返回。
----------------一个完整的例子-------------------------------
--一个完整的类型定义
CREATE OR REPLACE TYPE MyRectangle AS OBJECT(
--属性定义
length integer,
width integer,
--构造函数定义
CONSTRUCTOR FUNCTION MyRectangle(var_length number) RETURN SELF AS RESULT,
--过程定义
MEMBER PROCEDURE Inc(var_length integer,var_width integer),
MEMBER PROCEDURE Mini,
--函数定义
MEMBER FUNCTION GetLength RETURN integer,
MEMBER FUNCTION GetWidth RETURN integer,
MEMBER FUNCTION Scale(var_length integer,var_width integer) RETURN integer,
--比较方法定义
MAP MEMBER FUNCTION Compare RETURN integer
);
--/
CREATE OR REPLACE TYPE BODY MyRectangle IS
--构造函数定义
CONSTRUCTOR FUNCTION MyRectangle(var_length number) RETURN SELF AS RESULT IS
BEGIN
length := var_length;
width := 2;
RETURN;
END;
--过程定义
MEMBER PROCEDURE Inc(var_length integer,var_width integer) IS
BEGIN
length := length + var_length;
width := width + var_width;
END;
MEMBER PROCEDURE Mini IS
BEGIN
length := length - 1;
width := width -1;
END;
--函数定义
MEMBER FUNCTION GetLength RETURN integer IS
BEGIN
RETURN length;
END;
MEMBER FUNCTION GetWidth RETURN integer IS
BEGIN
RETURN width;
END;
MEMBER FUNCTION Scale(var_length integer,var_width integer) RETURN integer IS
BEGIN
RETURN (length + var_length) * (width + var_width);
END;
--比较方法定义
MAP MEMBER FUNCTION Compare RETURN integer IS
BEGIN
RETURN length * width;
END;
END;