通过使用SPL语言的对象类型规格和对象类型主体,创建对象类型并将其存储在数据库中。

  • 对象类型规格:这是指定对象类型的属性和方法特征的公共接口。
  • 对象类型主体:这包含对象类型规格中指定的方法的实现。

以下各节介绍了用于创建对象类型规格和对象类型主体的命令。

对象类型规格语法

下面是对象类型规格的语法:

CREATE [ OR REPLACE ] TYPE name
  [ AUTHID { DEFINER | CURRENT_USER } ]
  { IS | AS } OBJECT
( { attribute { datatype | objtype | collecttype } }
    [, ...]
  [ method_spec ] [, ...]
  [ constructor ] [, ...]
) [ [ NOT ] { FINAL | INSTANTIABLE } ] ...;

其中method_spec的语法如下:

[ [ NOT ] { FINAL | INSTANTIABLE } ] ...
[ OVERRIDING ]
  subprogram_spec

其中subprogram_spec的语法如下:

{ MEMBER | STATIC }
{ PROCEDURE proc_name
    [ ( [  SELF [ IN | IN OUT ] name ]
        [, parm1 [ IN | IN OUT | OUT ] datatype1
                 [ DEFAULT value1 ] ]
        [, parm2 [ IN | IN OUT | OUT ] datatype2
                 [ DEFAULT value2 ]
        ] ...)
    ]
|
  FUNCTION func_name
    [ ( [  SELF [ IN | IN OUT ] name ]
        [, parm1 [ IN | IN OUT | OUT ] datatype1
                 [ DEFAULT value1 ] ]
        [, parm2 [ IN | IN OUT | OUT ] datatype2
                 [ DEFAULT value2 ]
        ] ...)
    ]
  RETURN return_type
}

其中constructor的语法如下:

  CONSTRUCTOR func_name
    [ ( [  SELF [ IN | IN OUT ] name ]
        [, parm1 [ IN | IN OUT | OUT ] datatype1
                 [ DEFAULT value1 ] ]
        [, parm2 [ IN | IN OUT | OUT ] datatype2
                 [ DEFAULT value2 ]
        ] ...)
    ]
  RETURN self AS RESULT
说明 OR REPLACE选项当前不能用于添加、删除或修改现有对象类型的属性。可使用DROP TYPE命令首先删除现有对象类型。OR REPLACE选项可用于添加、删除或修改现有对象类型中的方法。

ALTER TYPE ALTER ATTRIBUTE命令的PostgreSQL形式可用于更改现有对象类型中属性的数据类型。不过,ALTER TYPE命令不能添加或删除对象类型中的属性。

name是分配给对象类型的标识符(可能是schema限定的)。

如果省略AUTHID子句或指定DEFINER,则对象类型所有者的权限用于确定对数据库对象的访问权限。如果指定CURRENT_USER,则执行对象中方法的当前用户的权限用于确定访问权限。

attribute是分配给对象类型的属性的标识符。

datatype是基本数据类型。

objtype是先前定义的对象类型。

collecttype是先前定义的集合类型。

CREATE TYPE定义的右圆括号后面的[ NOT ] FINAL指定是否可以从此对象类型派生子类型。FINAL是默认值,意味着不从此对象类型派生子类型。如果要允许在此对象类型下定义子类型,请指定NOT FINAL。

说明 即使在CREATE TYPE命令中接受NOT FINAL的规格,SPL当前也不支持创建子类型。

CREATE TYPE定义的右圆括号后面的[ NOT ] INSTANTIABLE指定是否可以创建此对象类型的对象实例。INSTANTIABLE是默认值,意味着可创建此对象类型的实例。如果此对象类型将仅用作要从中定义其他专用子类型的父模板,请指定NOT INSTANTIABLE。如果指定NOT INSTANTIABLE,则还必须指定NOTFINAL。如果对象类型中的任何方法包含NOT INSTANTIABLE限定符,则对象类型本身必须使用NOT INSTANTIABLE和NOT FINAL进行定义。

说明 即使在CREATE TYPE命令中接受NOT INSTANTIABLE的规格,SPL当前也不支持创建子类型。

method_spec指示成员方法或静态方法的规格。

在方法的定义之前,[ NOT ] FINAL指定该方法是否可以在子类型中重写。NOT FINAL是默认值,意味着该方法可以在子类型中重写。

在方法的定义之前,如果该方法在父类型中重写同名的方法,请指定OVERRIDING。重写方法必须具有与父类型中定义的相同数据类型和参数模式、相同顺序和相同返回类型(如果该方法是函数)的相同数量的同名方法参数。

在方法的定义之前,[ NOT ] INSTANTIABLE指定对象类型定义是否提供方法的实现。如果指定INSTANTIABLE,则对象类型的CREATE TYPE BODY命令必须指定方法的实现。如果指定NOT INSTANTIABLE,则对象类型的CREATE TYPE BODY命令不得包含方法的实现。在后一种情况下,假定子类型包含方法的实现,从而在此对象类型中重写方法。如果对象类型中存在任意NOT INSTANTIABLE方法,则对象类型定义本身必须在对象类型规格的右圆括号后面指定NOT INSTANTIABLE和NOTFINAL。默认值为INSTANTIABLE。

subprogram_spec指示存储过程或函数的规格,并以MEMBER或STATIC的规格开头。成员子程序必须根据特定的对象实例进行调用,而静态子程序不根据任何对象实例进行调用。

proc_name是存储过程的标识符。如果指定SELF参数,则name是CREATE TYPE命令中给出的对象类型名称。如果指定,则parm1, parm2, … 是存储过程的形参。datatype1, datatype2, …分别是parm1, parm2, …的数据类型。IN、IN OUT和OUT是每个形参的可能参数模式。如果未指定,则默认值为IN。value1, value2, …是可为IN参数指定的默认值。

包含CONSTRUCTOR关键字和函数定义将定义一个构造函数。

func_name是函数的标识符。如果指定SELF参数,则name是CREATE TYPE命令中给出的对象类型名称。如果指定,则 parm1, parm2, …是函数的形参。datatype1, datatype2, …分别是parm1, parm2, …的数据类型。IN、IN OUT和OUT是每个形参的可能参数模式。如果未指定,则默认值为 IN。value1, value2, …是可为 IN 参数指定的默认值。return_type是函数返回的值的数据类型。

对于对象类型规格,应注意以下几点:

  • 必须至少有一个对象类型中定义的属性。
  • 可以有一个或多个对象类型中定义的方法,也可以一个都没有。
  • 对于每个成员方法,都存在一个名为SELF的隐式内置参数,其数据类型是所定义的对象类型的数据类型。

    SELF引用当前正在调用方法的对象实例。SELF可显示声明为参数列表中的IN或IN OUT参数(例如,声明为MEMBERFUNCTION (SELF IN OUT object_type ...))。

    如果明确声明SELF,则SELF必须是参数列表中的第一个参数。如果未明确声明SELF,则其参数模式默认为IN OUT(对于成员存储过程)和IN(对于成员函数)。

  • 静态方法不能重写(OVERRIDING和STATIC不能在method_spec中一起指定)。
  • 静态方法必须是可实例化的(NOT INSTANTIABLE和STATIC不能在method_spec中一起指定)。

对象类型主体语法

下面是对象类型主体的语法:

CREATE [ OR REPLACE ] TYPE BODY name
  { IS | AS }
  method_spec [...]
  [constructor] [...]
END;

其中method_spec的语法如下:

subprogram_spec

subprogram_spec的语法如下:

{ MEMBER | STATIC }
{ PROCEDURE proc_name
    [ ( [  SELF [ IN | IN OUT ] name ]
        [, parm1 [ IN | IN OUT | OUT ] datatype1
                 [ DEFAULT value1 ] ]
        [, parm2 [ IN | IN OUT | OUT ] datatype2
                 [ DEFAULT value2 ]
        ] ...)
    ]
{ IS | AS }
  [ PRAGMA AUTONOMOUS_TRANSACTION; ]
  [ declarations ]
  BEGIN
    statement; ...
[ EXCEPTION
    WHEN ... THEN
      statement; ...]
  END;
|
  FUNCTION func_name
    [ ( [  SELF [ IN | IN OUT ] name ]
        [, parm1 [ IN | IN OUT | OUT ] datatype1
                 [ DEFAULT value1 ] ]
        [, parm2 [ IN | IN OUT | OUT ] datatype2
                 [ DEFAULT value2 ]
        ] ...)
    ]
  RETURN return_type
{ IS | AS }
  [ PRAGMA AUTONOMOUS_TRANSACTION; ]
  [ declarations ]
  BEGIN
    statement; ...
[ EXCEPTION
    WHEN ... THEN
      statement; ...]
  END;

其中constructor的语法如下:

  CONSTRUCTOR func_name
    [ ( [  SELF [ IN | IN OUT ] name ]
        [, parm1 [ IN | IN OUT | OUT ] datatype1
                 [ DEFAULT value1 ] ]
        [, parm2 [ IN | IN OUT | OUT ] datatype2
                 [ DEFAULT value2 ]
        ] ...)
    ]
  RETURN self AS RESULT
{ IS | AS }
  [ declarations ]
  BEGIN
    statement; ...
[ EXCEPTION
    WHEN ... THEN
      statement; ...]
  END;

name是分配给对象类型的标识符(可能是schema限定的)。

method_spec指示CREATE TYPE命令中已指定的可实例化方法的实现。

如果INSTANTIABLE已指定或在CREATE TYPE命令的method_spec中被忽略,则CREATE TYPE BODY命令中必须存在此方法的method_spec。

如果NOT INSTANTIABLE已在CREATE TYPE命令的method_spec中指定,则CREATE TYPE BODY命令中不得存在此方法的method_spec。

subprogram_spec指示存储过程或函数的规格,并以MEMBER或STATIC的规格开头。必须使用CREATE TYPE命令的subprogram_spec中指定的同一限定符。

proc_name是CREATE TYPE命令中指定的存储过程的标识符。参数声明具有与CREATE TYPE命令描述相同的含义,并且必须以CREATE TYPE命令中指定的同一方式在CREATE TYPE BODY命令中指定。

包含CONSTRUCTOR关键字和函数定义将定义一个构造函数。

func_name是CREATE TYPE命令中指定的函数的标识符。参数声明具有与CREATE TYPE命令描述相同的含义,并且必须以CREATETYPE命令中指定的同一方式在CREATETYPE BODY命令中指定。return_type是函数返回的值的数据类型,必须与CREATE TYPE命令中给出的return_type相匹配。

PRAGMA AUTONOMOUS_TRANSACTION是将存储过程或函数设置为自治事务的指令。

declarations是变量、游标、类型或子程序声明。如果包括子程序声明,则它们必须在所有其他变量、游标和类型声明之后。

statement是SPL程序语句。