#集合变量

YashanDB包含如下两种集合变量:

  • VARRAY:可变长数组,一个数组包含了一组相同类型的成员,这些成员在数组里有序存放。
  • NESTED TABLE:嵌套表,一个嵌套表包含了多行的相同类型成员,像物理表记录存储一样,这些行成员采取了无序存放的方式。

数组与嵌套表的显著区别为,数组在定义时必须声明其最大长度,实际长度(即成员个数)在此范围内动态改变;而嵌套表在资源允许范围内不存在最大长度限制,实际长度(即行成员个数)可一直动态扩展。

此外,使用嵌套表可以很方便地实现多维数组的定义和操作。

# 集合变量声明

声明集合变量前需进行集合类型的定义,除可以在过程体内部直接定义集合类型外,还可以作为UDT在过程体外部定义。在过程体内部定义的语法为:

varray_definition
TYPE varray_type IS VARRAY VARYING ARRAY ( size_limit ) OF datatype NOT NULL
nested_table_definition
TYPE nested_table_type IS TABLE OF ( datatype NOT NULL )

对集合变量的声明语法为:

syntax
variable_name varray_type nested_table_type ;

size_limit

在声明数组类型时,必须指定数组成员的个数上限,值范围[1,int32]。

datatype

成员的数据类型,可指定为PL/SQL支持的所有类型,或UDT。当数据类型为字符型时,须同时指定其Size属性,例如VARCHAR(10),但输入CHAR默认等同于CHAR(1);可指定的最大Size为32000。

NOT NULL

使用NOT NULL指定集合的成员不能设置为NULL,省略时,默认集合中的成员可以设置为NULL。

# 集合变量赋值

集合变量赋值包括初始化赋值和过程中赋值。

1.通过如下格式为集合成员赋值:

variable_name := (varray_type|nested_table_type) (expr1,expr2,...);

variable_name(index) := expr;

当成员类型为普通标量类型时,expr为一个YashanDB认可的通用表达式,否则为该成员类型所规定的赋值格式。

2.可以将一个已初始化值的集合变量赋值给另一个集合变量。

3.可以通过数组相关内置函数对数组进行赋值,例如STRING_TO_ARRAYARRAY_APPENDARRAY_REMOVEARRAY_REPLACE等。

# 集合变量访问

一个已被赋值的集合变量可以通过如下语法访问:

syntax
varray_type nested_table_type ( expr )

expr为一个YashanDB认可的通用表达式,其结果必须为一个数字,表示数组内索引。数组内索引以1为首位。

示例

CREATE OR REPLACE TYPE udt_object FORCE AS OBJECT (
	area_no CHAR(2),
    MAP MEMBER FUNCTION showArea RETURN VARCHAR
) NOT FINAL;
/
CREATE OR REPLACE TYPE BODY udt_object AS
	MAP MEMBER FUNCTION showArea RETURN VARCHAR AS
    BEGIN
		RETURN self.area_no;
	END;
END;
/ 

--通过VARRAY定义单维+嵌套数组并访问
DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	v_char1 char_array := char_array('1',TO_CHAR(2),'');
	v_char2 char_array := v_char1;
	TYPE array_array IS ARRAY(3) OF char_array;
	v_array array_array;
	TYPE udt_array IS ARRAY(3) OF udt_object;
	v_udt udt_array;
	TYPE rec IS RECORD(area udt_object, branch CHAR(4));
	TYPE rec_array IS ARRAY(3) OF rec;
	v_rec rec_array;
BEGIN
	DBMS_OUTPUT.PUT_LINE('char array:'||v_char2(1)||v_char2(TO_NUMBER('2'))||v_char2(3));
	v_array := array_array(v_char1,v_char2);
	DBMS_OUTPUT.PUT_LINE('array array:'||v_array(1)(1)||v_array(1)(2)||v_array(2)(1)||v_array(2)(2));
	v_udt := udt_array(udt_object('01'),udt_object('02'));
	DBMS_OUTPUT.PUT_LINE('udt array:'||v_udt(1).area_no||' '||v_udt(2).area_no);
	v_rec := rec_array(rec(udt_object('03'),'0301'),rec(udt_object('04'),'0401'));
	DBMS_OUTPUT.PUT_LINE('record array:'||v_rec(1).area.area_no||'.'||v_rec(1).branch||
    ' '||v_rec(2).area.area_no||'.'||v_rec(2).branch);
END;
/
--result
char array:12
array array:1212
udt array:01 02
record array:03.0301 04.0401  

--通过NESTED TABLE定义多维数组并访问
DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_table char_table;
BEGIN
	v_table := char_table(char_array('1',TO_CHAR(2),''),char_array('1',TO_CHAR(2),''));
	DBMS_OUTPUT.PUT_LINE('nested table: '||v_table(1)(1)||v_table(1)(2)||' '||v_table(2)(1)||v_table(2)(2));
END;
/
--result
nested table: 12 12

# 集合变量操作方法

除上述通过索引直接访问集合成员的方法外,YashanDB还内置了一系列方法,用于在过程体内对集合变量执行指定的操作。

需注意的是,除EXISTS外,其他方法都必须在集合变量初始化后才可以操作。

# LIMIT

syntax
varray_type nested_table_type . limit ()

LIMIT为一个函数,用于获得集合的成员数量上限,对于嵌套表,函数返回NULL。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array limit: '||v_char.LIMIT);
	DBMS_OUTPUT.PUT_LINE('nested table limit: '||v_t_char.LIMIT);
END;
/

--result
array limit: 5
nested table limit: 

# COUNT

syntax
varray_type nested_table_type . count ()

COUNT为一个函数,用于获得集合的当前成员数量。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array count: '||v_char.count());
	DBMS_OUTPUT.PUT_LINE('nested table limit: '||v_t_char.count());
END;
/

--result
array count: 3
nested count limit: 3

# FIRST

syntax
varray_type nested_table_type . first ()

FIRST为一个函数,用于获得集合当前第一个成员的索引。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array first: '||v_char.first());
	DBMS_OUTPUT.PUT_LINE('nested table first: '||v_t_char.first());
END;
/

--result
array first: 1
nested table first: 1

# LAST

syntax
varray_type nested_table_type . last ()

LAST为一个函数,用于获得集合当前最后一个成员的索引。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array last: '||v_char.last());
	DBMS_OUTPUT.PUT_LINE('nested table last: '||v_t_char.last());
END;
/

--result
array last: 3
nested table last: 3

# NEXT

syntax
varray_type nested_table_type . next ( expr )

NEXT为一个函数,用于获得输入索引在集合内的下一个索引。

expr为一个YashanDB认可的通用表达式,其结果必须为一个数字(为NULL时函数返回NULL),负数按0处理。当expr+1的值超出集合上下限范围时,函数返回空。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array next0: '||v_char.NEXT(0));
	DBMS_OUTPUT.PUT_LINE('array next-9: '||v_char.NEXT(-9));
	DBMS_OUTPUT.PUT_LINE('array next3: '||v_char.NEXT(3));
	DBMS_OUTPUT.PUT_LINE('nested table next0: '||v_t_char.NEXT(0));
	DBMS_OUTPUT.PUT_LINE('nested table next-9: '||v_t_char.NEXT(-9));
	DBMS_OUTPUT.PUT_LINE('nested table next3: '||v_t_char.NEXT(3));
END;
/

--result
array next0: 1
array next-9: 1
array next3: 
nested table next0: 1
nested table next-9: 1
nested table next3: 

# PRIOR

syntax
varray_type nested_table_type . prior ( expr )

PRIOR为一个函数,用于获得输入索引在集合内的下一个索引。

expr为一个YashanDB认可的通用表达式,其结果必须为一个数字(为NULL时函数返回NULL),负数按0处理。当expr-1的值超出集合上下限范围时,函数返回空。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array prior-9: '||v_char.PRIOR(-9));
	DBMS_OUTPUT.PUT_LINE('array prior1: '||v_char.PRIOR(1));
	DBMS_OUTPUT.PUT_LINE('array prior4: '||v_char.PRIOR(4));
	DBMS_OUTPUT.PUT_LINE('nested table prior-9: '||v_t_char.PRIOR(-9));
	DBMS_OUTPUT.PUT_LINE('nested table prior1: '||v_t_char.PRIOR(1));
	DBMS_OUTPUT.PUT_LINE('nested table prior4: '||v_t_char.PRIOR(4));
END;
/

--result
array prior-9: 
array prior1: 
array prior4: 3
nested table prior-9: 
nested table prior1: 
nested table prior4: 3

# EXISTS

syntax
varray_type nested_table_type . exists ( expr )

EXISTS为一个函数,用于判断输入索引位置是否有成员存在。

expr为一个YashanDB认可的通用表达式,其结果必须为一个数字(为NULL时函数返回NULL)。

示例

DECLARE
	TYPE char_array IS ARRAY(5) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	DBMS_OUTPUT.PUT_LINE('array exists-9: '||v_char.EXISTS(-9));
	DBMS_OUTPUT.PUT_LINE('array exists1: '||v_char.EXISTS(1));
	DBMS_OUTPUT.PUT_LINE('array exists4: '||v_char.EXISTS(4));
	DBMS_OUTPUT.PUT_LINE('nested table exists-9: '||v_t_char.EXISTS(-9));
	DBMS_OUTPUT.PUT_LINE('nested table exists1: '||v_t_char.EXISTS(1));
	DBMS_OUTPUT.PUT_LINE('nested table exists4: '||v_t_char.EXISTS(4));
END;
/

--result
array exists-9: false
array exists1: true
array exists4: false
nested table exists-9: false
nested table exists1: true
nested table exists4: false

# EXTEND

syntax
varray_type nested_table_type . extend ( expr1 , expr2 )

EXTEND为一个存储过程,用于拓展集合的当前成员数量,扩展值为expr2所在成员值,拓展个数为expr1个(对于数组,拓展后成员数量不能超过数组上限)。

expr1/expr2为一个YashanDB认可的通用表达式,其结果必须为一个非负数字(为NULL时表示extend(0))。expr2省略时,表示拓展空值,expr1省略时,表示拓展1个。

示例

DECLARE
	TYPE char_array IS ARRAY(10) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','3');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	v_char.EXTEND();
	v_char.EXTEND(1);
	v_char.EXTEND(1,1);
	v_t_char.EXTEND();
	v_t_char.EXTEND(1);
	v_t_char.EXTEND(1,1);
	DBMS_OUTPUT.PUT_LINE('array count: '||v_char.count());
	DBMS_OUTPUT.PUT_LINE('nested table count: '||v_t_char.count());
END;
/

--result
array count: 6
nested table count: 6

# TRIM

syntax
varray_type nested_table_type . trim ( expr )

TRIM为一个存储过程,用于删除集合的末尾expr个成员(删除数量不能超过集合当前成员数量)。

expr为一个YashanDB认可的通用表达式,其结果必须为一个非负数字(为NULL时表示trim(0))。expr省略时,表示删除1个成员。

示例

DECLARE
	TYPE char_array IS ARRAY(10) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','3');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	v_char.trim('');
	v_char.trim;
	v_char.trim(2);
	v_t_char.trim('');
	v_t_char.trim;
	v_t_char.trim(2);
	DBMS_OUTPUT.PUT_LINE('array count: '||v_char.count());
	DBMS_OUTPUT.PUT_LINE('nested table count: '||v_t_char.count());
END;
/

--result
array count: 0
nested table count: 0

# DELETE

syntax
varray_type nested_table_type . delete ()

DELETE为一个存储过程,用于清空集合中的所有成员。

示例

DECLARE
	TYPE char_array IS ARRAY(10) OF CHAR;
	TYPE char_table IS TABLE OF char_array;
	v_char char_array := char_array('1','2','3');
	v_t_char char_table := char_table(v_char, v_char, v_char);
BEGIN
	v_char.DELETE;
	v_t_char.DELETE;
	DBMS_OUTPUT.PUT_LINE('array count: '||v_char.count());
	DBMS_OUTPUT.PUT_LINE('nested table count: '||v_t_char.count());
END;
/

--result
array count: 0
nested table count: 0