#集合变量
YashanDB包含如下两种集合变量:
- VARRAY:可变长数组,一个数组包含了一组相同类型的成员,这些成员在数组里有序存放。
- NESTED TABLE:嵌套表,一个嵌套表包含了多行的相同类型成员,像物理表记录存储一样,这些行成员采取了无序存放的方式。
数组与嵌套表的显著区别为,数组在定义时必须声明其最大长度,实际长度(即成员个数)在此范围内动态改变;而嵌套表在资源允许范围内不存在最大长度限制,实际长度(即行成员个数)可一直动态扩展。
此外,使用嵌套表可以很方便地实现多维数组的定义和操作。
# 集合变量声明
声明集合变量前需进行集合类型的定义,除可以在过程体内部直接定义集合类型外,还可以作为UDT在过程体外部定义。在过程体内部定义的语法为:
对集合变量的声明语法为:
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_ARRAY、ARRAY_APPEND、ARRAY_REMOVE、ARRAY_REPLACE等。
# 集合变量访问
一个已被赋值的集合变量可以通过如下语法访问:
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
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
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
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
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
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
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
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
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
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
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