PolarDB PostgreSQL版(兼容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 PostgreSQL版(兼容Oracle)支持的任何类型的名称。
- 任何复合类型的名称。
- 通过%TYPE运算符固定的列。
- 另一种子类型的名称。
包括constraint子句以定义支持精度或小数位数的类型的限制。
- precision:precision指定子类型值中允许的总位数。
- scale:scale指定子类型值中允许的小数位数。
- length:length 指定CHARACTER、VARCHAR或TEXT基本类型值中允许的总长度。
包括NOTNULL子句以指定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 PostgreSQL版(兼容Oracle)不会实施子类型约束。
- 调用过程时,如果将实参分配给形参,则PolarDB PostgreSQL版(兼容Oracle)会实施子类型约束。
使用 %TYPE 运算符
您可以使用%TYPE表示法声明固定到列的子类型。例如:
SUBTYPE emp_type IS emp.empno%TYPE
此命令创建名为emp_type的子类型,其基本类型匹配emp表中empno列的类型。基于列的子类型将共享列大小约束;NOT NULL和CHECK约束不会继承。
子类型转换
不受约束的子类型是其所基于的类型的别名。子类型(不受约束)的任何类型变量都可以与基本类型的变量互换而无需转换,反之亦然。
受约束子类型的变量可以与基本类型的变量互换而无需转换,但基本类型的变量只能在符合子类型约束时与受约束的子类型互换。如果基于相同的子类型,则受约束子类型的变量可以隐式地转换为另一个子类型,并且约束值在其所转换的子类型值范围内。