用户自定义子类型
PL/SQL中使用SUBTYPE可以创建自己的子类型,其基类型可以是任何基础类型或用户自定义类型。子类型可以提供数据类型的兼容性,显示该类型数据项的预期用途,检测超出范围的值。
SUBTYPE基础定义语法:
SUBTYPE subtype_name IS base_type [ { ( precision [, scale ] ) | RANGE low_value .. high_value } ] [ NOT NULL ]
参数说明:
- SUBTYPE:SUBTYPE关键字。
- subtype_name:需要定义的SUBTYPE子类型名。
- base_type:基类型,创建subtype类型所依据的基础类型或者自定义类型。
- precision [, scale ]:可添加的typmod约束。
- RANGE low_value .. high_value:可添加的RANGE约束。
- NOT NULL:可添加的NOT NULL约束。
- base_type支持基础类型,也支持自定义数据类型以及SUBTYPE类型。
- 如果指定了typmod约束,则对SUBTYPE类型变量进行赋值时会校验该值是否符合typmod约束,是否支持指定typmod约束与基类型保持一致。
- 仅int类型支持指定RANGE约束,其中包括TINYINT/SMALLINT/MEDIUMINT/INTEGER/BINARY_INTEGER/BIGINT/INT。如果指定了RANGE约束,则对SUBTYPE类型变量进行赋值时会校验该值是否在指定的范围内。
- RANGE的上下限不能超过INT64。
- 暂不支持创建变量的时候使用RANGE约束。
- 嵌套SUBTYPE类型和创建SUBTYPE类型变量时更新约束情况。
- 如果指定了NOT NULL,则使用SUBTYPE类型定义变量时必须初始化,且不能赋NULL值。
- 支持使用SUBTYPE类型作为存储过程出入参类型。
- 支持SUBTYPE类型变量使用%type和%rowtype,其中%type支持所有基类型,%rowtype支持表、不支持集合类型。
- SUBTYPE支持使用基类型的类型构造器。
- 不支持指定字符集。
- 仅A兼容模式下支持使用。
- 数据库从不支持SUBTYPE的版本升级到支持SUBTYPE的版本,在升级未提交状态,不支持使用SUBTYPE。
示例1:无约束子类型。
gaussdb=# DECLARE
SUBTYPE sint IS INT;
a sint := 2147483647;
BEGIN
DBE_OUTPUT.PUT_LINE('a = ' || a);
END;
/
a = 2147483647
ANONYMOUS BLOCK EXECUTE
示例2:SUBTYPE支持typmod、RANGE和NOT NULL约束。
--typmod约束 gaussdb=# DECLARE SUBTYPE sdec IS DECIMAL(3,2) NOT NULL; a sdec := 1.1; b sdec(5,2) := 322.1; BEGIN DBE_OUTPUT.PUT_LINE('a = ' || a); DBE_OUTPUT.PUT_LINE('b = ' || b); END; / a = 1.10 b = 322.10 ANONYMOUS BLOCK EXECUTE --NOT NULL约束 gaussdb=# DECLARE SUBTYPE sint IS INT NOT NULL; a sint; BEGIN NULL; END; / ERROR: variables declared as NOT NULL must have a default value. CONTEXT: compilation of PL/pgSQL function "inline_code_block" near line 2 gaussdb=# DECLARE SUBTYPE age IS BINARY_INTEGER RANGE 0..100 NOT NULL; a age := 18; b age := 20; BEGIN DBE_OUTPUT.PUT_LINE('a的年龄为:' || a); DBE_OUTPUT.PUT_LINE('b的年龄为:' || b); END; / a的年龄为:18 b的年龄为:20 ANONYMOUS BLOCK EXECUTE
示例3:SUBTYPE嵌套自定义数据类型使用基类型类型构造器。
gaussdb=# DECLARE
TYPE arrint IS VARRAY(10) OF INTEGER;
SUBTYPE sarrint IS arrint;
--a sarrint := sarrint(1,2,3,4);报错,仅支持基类型的类型构造器
a sarrint := arrint(1,2,3,4);
BEGIN
FOR i IN 1..4 LOOP
DBE_OUTPUT.PUT_LINE(a(i));
END LOOP;
END;
/
1
2
3
4
ANONYMOUS BLOCK EXECUTE
示例4:支持SUBTYPE嵌套SUBTYPE类型,并更新约束条件。
--range约束
gaussdb=# DECLARE
SUBTYPE sint IS INTEGER RANGE 10..99;
SUBTYPE ssint IS sint RANGE 0..9;
a sint := 50;
b ssint := 5;
BEGIN
DBE_OUTPUT.PUT_LINE('a = ' || a);
DBE_OUTPUT.PUT_LINE('b = ' || b);
END;
/
a = 50
b = 5
ANONYMOUS BLOCK EXECUTE
--typmod约束
gaussdb=# DECLARE
SUBTYPE word IS VARCHAR2(5);
SUBTYPE sentence IS word(50);
a word := 'Tom';
b sentence := 'Tom and Jerry';
c sentence(8) := 'Mountain';
BEGIN
DBE_OUTPUT.PUT_LINE('a = ' || a);
DBE_OUTPUT.PUT_LINE('b = ' || b);
DBE_OUTPUT.PUT_LINE('c = ' || c);
END;
/
a = Tom
b = Tom and Jerry
c = Mountain
ANONYMOUS BLOCK EXECUTE
示例5:支持自定义数据类型嵌套SUBTYPE类型。
gaussdb=# DECLARE
SUBTYPE sint IS BINARY_INTEGER RANGE 0..99;
TYPE tabint IS TABLE OF sint;
a tabint := tabint();
BEGIN
a.EXTEND(10);
a(1) := 50;
END;
/
ANONYMOUS BLOCK EXECUTE