通过使用 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,则还必须指定 NOT FINAL。如果对象类型中的任何方法包含 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 和 NOT FINAL。默认值为 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 参数(例如,声明为 MEMBER FUNCTION (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 命令描述相同的含义,并且必须以 CREATE TYPE 命令中指定的同一方式在 CREATE TYPE BODY 命令中指定。return_type 是函数返回的值的数据类型,必须与 CREATE TYPE 命令中给出的 return_type 相匹配。

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

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

statement 是 SPL 程序语句。