跳到主要内容

自定义类型

自定义类型包括对象类型、集合类型。嵌套表类型和可变数组统称为集合类型。

对象类型只能使用 CREATE TYPE 语句进行创建,然后在PLSQL中使用。集合类型可以使用CREATE TYPE 语句创建,也可以在PL\SQL中临时声明并使用。

可变数组是从0到声明的最大的尺寸的个数组。访问时可以使用语法:variable_name(index),index的最小值是1。访问到的值会因元素的删除或者增加而不同。

CREATE TYPE语句创建自定义类型

使用CREATE TYPE语句可以将自定义类型存储到数据库中复用。

参数说明:

元素描述限制语法
typename自定义类型名称符合8s的命名规则,长度最长128字符标识符

说明及限制:

  • [OR REPLACE]如果存在同名的自定义类型则覆盖。8s仅语法支持。
  • 8s本版本暂不支持使用ALTER TYPE修改已创建的对象类型。

对象类型

对象类型中包含方法及属性。

Object_Type_Def:=

说明及限制:

  • 不支持创建对象表。
  • 不支持定义为表中列。
  • 不支持在SQL中使用对象类型。

Attribute_Define_Clause:=

属性定义在对象类型中是不可缺少的。

参数说明:

元素描述限制语法
attribute_name对象类型的属性名称长度最长128字符,在创建的类型中必须是唯一的标识符
datatype属性对应的类型包括8s中基础数据类型及支持的自定义类型数据类型

例如:创建简单对象类型,只包含属性,不包含方法。

> create or replace type person_typ1 as object
(
name varchar2(10),
gender varchar2(10),
birthdate date
);
/
Oracle Type created.

说明及限制:

  • 不能在属性上增加NOT NULL约束。
  • 不支持%rowtype和%type定义对象类型属性的数据类型。
  • 不支持byte,text,serial,bigserial,serial8,boolean,timestamp with time zone定义对象类型属性的数据类型。
  • 不支持集合类型list,set,multiset定义对象类型属性的数据类型。
  • 不支持对象类型属性定义中指定ref关键字。
  • 不支持对象类型属性是package中定义的集合类型。

Method_Define_Clause

方法在对象类型中可以缺省,通常表示为过程和函数,在此处只进行方法的声明,具体实现需要在CREATE TYPE BODY中进行。

目前支持 MEMBER 方法和STATIC:

MEMBER 方法是需要对对象进行实例化才可以调用的方法,并且在 MEMBER 方法的方法体中有一个隐式的参数self,它表示调用该方法的对象,self参数可以隐式或显示引用。

STATIC方法可以在对象类型上执行全局操作,而不需要访问特定对象实例的数据。与MEMBER方法相比,STATIC方法只能由对象类型调用,不能由对象实例调用,且静态方法不会默认将self值作为第一个参数传入。

procedure_spec:=

以过程的形式声明对象类型的方法。

参数说明:

元素描述限制语法
procedure_name过程名称必须满足名称限制的字符串标识符

Parameter_Declaration:=

声明方法中的参数声明。

参数说明:

元素描述限制语法
parameter参数名称必须满足名称限制的字符串标识符
datatype参数类型支持8s中基础数据类型及支持的自定义类型数据类型

function_spec:=

以函数的形式声明对象类型的方法

参数说明:

元素描述限制语法
function_name函数名称必须满足名称限制的字符串标识符
datatype参数数据类型类型在数据库中必须存在数据类型

示例

分别创建一个包含了声明MEMBER过程和MEMBER函数的对象类型。

>create type tp1 as object(
c1 int,
c2 int,
member function f1(c1 decimal(18,2)) return decimal(18,2)
);
/
Oracle Type created.
>create type tp1 as object(
c1 int,
c2 int,
member procedure p1(c1 decimal(18,2))
);
/
Oracle Type created.
>create or replace type obj is object (
type_name char(20),
id int,
member function func2(self in out obj) return int
);
/
Oracle Type created.

创建一个包含了声明STATIC方法的对象类型。

>create or replace type obj_typ is object (
id int,
static function get_id1(obj in out obj_typ) return int,
static procedure get_id2(obj in out obj_typ)
);
/

创建一个同时包含MEMBER方法和STATIC方法的对象类型。

>create or replace type obj_typ is object (
id int,
static function get_id2(obj in out obj_typ) return int,
member function get_id1(self in out obj_typ,p1 int) return int
);
/

说明及限制:

  • 不支持MEMBER方法参数指定self in out nocopy。

constructor_spec::=

自定义构造函数用来个性化构造一个对象的实例。

ConstructorFunction

参数说明:

元素描述限制语法
function_name函数名称必须满足名称限制的字符串标识符
datatype参数数据类型类型在数据库中必须存在数据类型

用法及限制

  • 自定义构造函数的名称必须与类型名称一致。
  • 入参如果包含self参数,则self参数必须为in out,且self参数类型必须与创建的object类型相同。
  • 返回值不以类型标识,使用特殊语法 return self as result。
  • object 自定义构造函数必须为function。
  • 创建类型头时允许声明重名函数。
  • 不对类型头中定义的函数参数进行校验。
  • 调用构造函数时,会默认在系统构造函数和所有自定义构造函数中寻找匹配度最高的函数调用,匹配规则与member,static方法相同。
  • 与系统默认相同,自定义构造函数后不允许存在其他表达式,例如constr().a 和constr()(a) 都会报错。

嵌套表类型

嵌套表类型是一组不同类型或者相同类型数据的集合,不限制集合元素个数。

Nested_Table_Type_Spec:=

例如:创建一个嵌套表类型,并在PLSQL中引用。

> create type mytype is table of varchar(20);
/

Oracle Type created.

declare
  c2 mytype;
begin
  c2:=mytype('SMTIH','ALIEN','SCOTT','TOM');
  dbms_output.put_line(c2(2));
end;
/ 

ALIEN

PL/SQL procedure successfully completed.

说明及限制:

  • ORACLE模式下运行
  • 类型不支持serial、serial8、bigserial数据类型
  • 不支持定义为表中列。

可变数组类型

可变数组类型是一有序的类型相同的元素集合。

Varay_Type_Spec:=

参数说明:

元素描述限制语法
size_limit最大元素限制整数值数值
datatype数据类型基础数据类型以及自定义数据类型标识符

例如:定义一个可变数组并在PLSQL中引用它。

create type mytype is varray(10) of varchar(20);
/

Oracle Type created.


declare
c2 mytype;
begin
c2:=mytype('SMTIH','ALIEN','SCOTT','TOM');
dbms_output.put_line(c2(2));
end;
> /

PL/SQL procedure successfully completed.

ALIEN

说明及限制:

  • ORACLE模式下运行
  • 类型不支持serial、serial8、bigserial数据类型
  • 不支持定义为表中列。

CREATE TYPE BODY语句创建自定义类型体

用来定义或实现使用CREATE TYPE语句创建的对象类型中定义的方法。

参数说明:

元素描述限制语法
typename对象体的名称必须与创建的对象名称一致标识符

Subprog_Decl_In_Type:=

对象类型中定义的方法的类型。

存储过程实现

Proc_Imp_Clause:=

descript

参数说明:

元素描述限制语法
procedure_name存储过程的名称与对象类型声明中的存储过程名称一致标识符

Declare_Section和body分别为声明部分和块的执行部分,详情请参考《GBase 8s V8.8 PLSQL 手册》中包的创建。

函数实现

Func_Imp_Clause:=

实现对象类型中声明的函数。

参数说明:

元素描述限制语法
function_name函数的名称与对象类型声明中的函数名称一致标识符
datatype函数的返回类型包括8s中基础数据类型及支持的自定义类型数据类型

示例

创建包含方法的对象类型并实现

>create or replace type obj_typ is object (
id int,
static function get_id2(obj in out obj_typ) return int,
member function get_id1(self in out obj_typ,p1 int) return int
);
/
>create or replace type body obj_typ is
static function get_id2(obj in out obj_typ) return int as
begin
 return obj.id;
end;
member function get_id1(self in out obj_typ,p1 int) return int is
begin
 self.id := p1;
return self.id;
end;
end;
/
>declare
 var1 obj_typ := obj_typ(100);
begin
 dbms_output.put_line(var1.get_id1(200));
 dbms_output.put_line(obj_typ.get_id2(var1));
end;   
/

说明及限制:

  • 不支持对象类型定义重名MEMBER方法或STATIC方法。
  • 不支持定义方法名称为GBase特殊表达式,如volume,否则创建类型体会报错。

暂不支持使用DROP TYPE BODY语句删除已创建的类型体,删除对象类型自动删除对应的类型体。

constructor_declaration::=

ConstructorFunctionBody

参数说明:

元素描述限制语法
datatype函数的返回类型包括8s中基础数据类型及支持的自定义类型数据类型
declare_section变量声明部分与存储过程函数限制相同表达式
body程序主体与存储过程函数限制相同表达式

用法及限制

  • 自定义构造函数的名称必须与类型名称一致。
  • 入参如果包含self参数,则self参数必须为in out,且self参数类型必须与创建的object类型相同。
  • 返回值不以类型标识,使用特殊语法 return self as result。
  • 构造函数类型体中的return语句不允许接表达式,使用'return'即可。
  • 创建类型体时不允许声明重名函数。
  • 若出现类型头中函数的参数个数与类型体中的参数个数不一致时,函数参数以类型体为准。

应用样例

create or replace type color as object(
red int,
constructor function color(self in out color) return self as result,
member function to_string return varchar2
);
/

create or replace type body color as
constructor function color(self in out color) return self as result is
begin
self.red := 255;
return;
end;
member function to_string return varchar2 is
begin
return '('|| self.red ||')';
end;
end;
/

declare
v_line_color color;
begin
v_line_color:=color();
dbms_output.put_line(v_line_color.to_string());
end;
/

集合类型在PL/SQL中应用

在PLSQL中,8s支持两种集合类型,可变数组和嵌套表。

元素描述限制语法
typename自定义类型的名称符合8s名称定义规则标识符

嵌套表类型的声明和使用

Nested_Table_Type_Spec:=

参数说明:

元素描述限制语法
datatype数据类型基础数据类型以及自定义数据类型标识符

例如:在下面应用场景中使用嵌套表类型。

--在PLSQL中定义并初始化嵌套表类型
declare
  type mytype is table of varchar(20);
  c2 mytype;
begin
  c2:=mytype('SMTIH','ALIEN','SCOTT','TOM');
  dbms_output.put_line(c2(2));
end;
/ 

ALIEN

PL/SQL procedure successfully completed.

--在PLSQL中定义多维数组
DECLARE
TYPE tb1 IS TABLE OF VARCHAR2(20);
vtb1 tb1 := tb1('one', 'three');
>
TYPE ntb1 IS TABLE OF tb1;
vntb1 ntb1 := ntb1(vtb1);
>
TYPE tv1 IS VARRAY(10) OF INTEGER;
TYPE ntb2 IS TABLE OF tv1;
vntb2 ntb2 := ntb2(tv1(3,5), tv1(5,7,3));
>
BEGIN
dbms_output.put_line('result:'|| vntb1(1)(1));
dbms_output.put_line('result:'|| vntb2.count);
END;
> /

PL/SQL procedure successfully completed.

result:one
result:2

说明及限制:

  • ORACLE模式下运行
  • 类型不支持serial、serial8、bigserial数据类型

可变数组的声明和使用

Varay_Type_Spec:=

参数说明:

元素描述限制语法
size_limit最大元素限制整数值数值
datatype数据类型基础数据类型以及自定义数据类型标识符

例如:在下面应用场景中使用数组类型。

declare
type mytype is varray(10) of varchar(20);
c2 mytype;
begin
c2:=mytype('SMTIH','ALIEN','SCOTT','TOM');
dbms_output.put_line(c2(2));
end;
> /

PL/SQL procedure successfully completed.

ALIEN

说明及限制:

  • ORACLE模式下运行
  • 类型不支持serial、serial8、bigserial数据类型