POLARDB for Oracle 支持用户定义的 PL/SQL 子类型和(子类型)别名。子类型是具有一组可选约束的数据类型,这些约束限制可以存储在该类型的列中的值。适用于该子类型所基于的类型的规则仍然适用,但您可以使用其他约束限制该类型中存储值的精度或小数位数。

您可以在 PL 函数、存储过程、匿名块或包的声明中定义子类型。语法如下:

SUBTYPE subtype_name IS type_name[(constraint)] [NOT NULL]

其中 constraint 为:

{precision [, scale]} | length

其中:

  • subtype_name:subtype_name 指定子类型的名称。
  • type_name:type_name 指定子类型所基于的原始类型的名称。

    type_name 可能是:

    • POLARDB for Oracle 支持的任何类型的名称。
    • 任何复合类型的名称。
    • 通过 %TYPE 运算符固定的列。
    • 另一种子类型的名称。

包括 constraint 子句以定义支持精度或小数位数的类型的限制。

  • precision:precision 指定子类型值中允许的总位数。
  • scale:scale 指定子类型值中允许的小数位数。
  • length:length 指定 CHARACTER、VARCHAR 或 TEXT 基本类型值中允许的总长度。

包括 NOT NULL 子句以指定 NULL 值可不存储在指定子类型的列中。

请注意,基于列的子类型将继承列大小约束,但该子类型不会继承 NOT NULL 或 CHECK 约束。

不受约束的子类型

要创建不受约束的子类型,请使用 SUBTYPE 命令指定新子类型名称和该子类型所基于类型的名称。例如,以下命令会创建一个名为 address 的子类型,该子类型具有类型 CHAR 的所有属性:

SUBTYPE address IS CHAR;

您还可以创建另一个子类型的子类型(受约束或不受约束):

SUBTYPE cust_address IS address NOT NULL;

此命令创建名为 cust_address 的子类型,该子类型共享 address 子类型的所有属性。包括 NOT NULL 子句以指定 cust_address 的值可能并非 NULL。

受约束的子类型

基于字符类型创建子类型时包括 length 值以定义子类型的最大长度。例如:

SUBTYPE acct_name IS VARCHAR (15);

此示例基于 VARCHAR 数据类型创建名为acct_name 的子类型,但限制为 15 个字符长度。

约束数字基本类型时,包括 precision(指定子类型值中的最大位数)和可选的 scale(指定小数点右侧的位数)的值。例如:

SUBTYPE acct_balance IS NUMBER (5, 2);

此示例创建名为 acct_balance 的子类型,该子类型共享 NUMBER 类型的所有属性,但小数点左侧不得超过 3 位数,小数点右侧不得超过 2 位数。

参数声明(在函数或存储过程标头中)为形参。传递给函数或存储过程的值为实参。调用函数或存储过程时,调用方提供(0 个或更多)实参。每个实参都分配给一个形参,该形参将值保存在函数或存储过程的主体内。

如果将形参声明为受约束的子类型:

  • 调用函数时,如果将实参分配给形参,则 POLARDB for Oracle 不会实施子类型约束。
  • 调用过程时,如果将实参分配给形参,则 POLARDB for Oracle 会实施子类型约束。

使用 %TYPE 运算符

您可以使用 %TYPE 表示法声明固定到列的子类型。例如:

SUBTYPE emp_type IS emp.empno%TYPE

此命令创建名为 emp_type 的子类型,其基本类型匹配 emp 表中 empno 列的类型。基于列的子类型将共享列大小约束;NOT NULL 和 CHECK 约束不会继承。

子类型转换

不受约束的子类型是其所基于的类型的别名。子类型(不受约束)的任何类型变量都可以与基本类型的变量互换而无需转换,反之亦然。

受约束子类型的变量可以与基本类型的变量互换而无需转换,但基本类型的变量只能在符合子类型约束时与受约束的子类型互换。如果基于相同的子类型,则受约束子类型的变量可以隐式地转换为另一个子类型,并且约束值在其所转换的子类型值范围内。