集合类型是多个相同类型分量的集合,类似于高级语言中的数组。通常,在PL/SQL程序中,记录类型对应一条记录中若干个字段的集合,而集合对应于表中某一列的多个值的集合。
在Oracle当中集合类型分为联合数组(Associative Array)、嵌套表(Nested Table)和可变数组(Variable-Size Array)三种类型。
联合数组:又称索引表,通过数字或字符串作为下标来查找集合中的元素,元素数量不限,只能用于PL/SQL环境。
嵌套表:与联合数组类似,但可以存储可变数量的元素。在数据库中,嵌套表是存储一组值的列类型,元素没有特定顺序,使用有序数字作为元素的下标,元素的最大数量不限。
可变数组:VARRAY是一种一维数组,使用有序数字作为元素的下标,元素的最大数量在定义时确定。
1. 关联数组(Associative Arrays)
联合数组又称索引表(Index-by table),是相同类型数据的集合,是键值(Key-Value)对的集合。每个键是唯一的索引值,没有固定的上下限,即元素个数是不受限制的,而且其索引值可以是无序的。索引值类型可以是字符类型(VARCHAR2、VARCHAR、LONG等),也可以是数字类型(PL_INTEGER、BINARY_INTEGER)。
语法定义
TYPE table_type_name IS TABLE OF datatype [NOT NULL] INDEX BY [PLS_INTEGER | BINARY_INTEGER | VARCHAR2(size_limit)]; 其中datatype是数组元素的数据类型,index_type是索引的数据类型,可以是整数或字符串。
声明关联数组变量
DECLARETYPE AssocArray IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER;my_array AssocArray;BEGIN-- ...END;
声明一个关联数组变量,使用已定义的关联数组类型。
访问和赋值
my_array(1) := 'HALO';my_array(2) := 'Associative Arrays';
使用索引访问和赋值关联数组的元素。
示例
DECLARETYPE AssocArray IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER;my_array AssocArray;BEGINmy_array(1) := 'HALO';my_array(2) := 'Associative Arrays';DBMS_OUTPUT.PUT_LINE(my_array(1) || ' ' || my_array(2));END;/

2. 嵌套表(Nested Tables)
嵌套表就像一个具有任意数量元素的一维数组。但是,嵌套表与数组在以下几个方面不同 -
数组是一个有声明数量的元素集合,但是一个嵌套的表没有。嵌套表的大小可以动态增加。
数组总是密集的,即它总是具有连续的下标。嵌套数组最初是密集的,但是当从其中删除元素时,它可能变得稀疏。
语法定义
-- 在Package或匿名块中TYPE type_name IS TABLE OF element_type [NOT NULL];-- 在SQL场景中,创建全局的嵌套表类型CREATE TYPE type_name IS TABLE OF element_type [NOT NULL];
与联合数组不同,没有INDEX BY子句,嵌套表下标是从1开始,并且对下标上限大小没有限制。
声明嵌套表变量
DECLARETYPE NestedTable IS TABLE OF VARCHAR2(100);my_table NestedTable;BEGIN-- ...END;
声明一个嵌套表变量,使用已定义的嵌套表类型。
访问和赋值
my_table := NestedTable('HALO', 'Nested Tables');my_table.EXTEND;my_table(3) := 'Database';
示例
DECLARETYPE NestedTable IS TABLE OF VARCHAR2(100);my_table NestedTable;BEGINmy_table := NestedTable('HALO', 'Nested Tables');my_table.EXTEND;my_table(3) := 'Database';FOR i IN 1..my_table.COUNT LOOPDBMS_OUTPUT.PUT_LINE(my_table(i));END LOOP;END;/CREATE TYPE StringTable AS TABLE OF VARCHAR2(100);DECLAREmy_table StringTable; -- 声明一个嵌套表变量BEGIN-- 初始化嵌套表my_table := StringTable('HALO', 'Nested Tables');-- 添加元素my_table.EXTEND;my_table(3) := 'Database';-- 访问和输出元素FOR i IN 1..my_table.COUNT LOOPDBMS_OUTPUT.PUT_LINE(my_table(i));END LOOP;END;/

3. 可变长数组(VARRAY)
变长数组也是一个一维数组,类似于嵌套表,可以作为表列和对象类型属性的数据类型,嵌套表的元素个数没有限制,而变长数组的元素个数是有限制的。
语法定义
-- 在Package或匿名块中TYPE type_name IS {VARRAY | VARYING ARRAY} (size_limit) OF element_type [NOT NULL];-- 在SQL场景中,创建全局的可变数组类型CREATE TYPE type_name IS {VARRAY | VARYING ARRAY} (size_limit)OF element_type [NOT NULL];
声明VARRAY变量
DECLARETYPE VarArray IS VARRAY(5) OF VARCHAR2(100);my_varray VarArray;BEGIN-- ...END;
声明一个VARRAY变量,使用已定义的VARRAY类型。
访问和赋值
my_varray := VarArray('HALO', 'VARRAY');my_varray(1) := 'Database';
示例
DECLARETYPE VarArray IS VARRAY(5) OF VARCHAR2(100);my_varray VarArray := VarArray('HALO', 'VARRAY');BEGINmy_varray(1) := 'Database';FOR i IN 1..my_varray.COUNT LOOPDBMS_OUTPUT.PUT_LINE(my_varray(i));END LOOP;END;/CREATE TYPE NumberArray AS VARRAY(10) OF NUMBER;DECLAREmy_varray NumberArray; -- 声明一个 VARRAY 变量BEGIN-- 初始化 VARRAYmy_varray := NumberArray(1, 2, 3, 4, 5);-- 访问和输出元素FOR i IN 1..my_varray.COUNT LOOPDBMS_OUTPUT.PUT_LINE('Element ' || i || ': ' || my_varray(i));END LOOP;END;/

4.集合方法
集合方法是一系列返回有关集合的信息的函数或对集合进行操作的过程,集合方法可以出现在PL/SQL除了SQL语句中的任何位置。集合方法使集合更易于使用,并且使应用程序更易于维护。
| 方法 | 描述 |
|---|---|
| DELETE | 从集合中删除元素。如果指定了数量,则删除指定位置上的元素,否则删除全部元素。 |
| TRIM | 从变长数组或嵌套表中删除末尾的元素位置。如果指定了数量,删除指定数量的元素位置,否则删除最后一个元素位置。 |
| EXTEND | 在变长数组或嵌套表的末尾创建一个新的元素位置,并将该位置上的值设置为NULL。如果指定了数量,则创建指定数量的元素位置。 |
| EXISTS | 检查集合的特定位置上的元素是否存在。 |
| FIRST | 返回使用整数下标的集合中的第一个(最小)索引编号。 |
| LAST | 返回使用整数下标的集合中的最后(最大)索引编号。 |
| COUNT | 返回集合的元素个数。 |
| LIMIT | 返回集合类型的最大元素限制。对于嵌套表和关联数组,返回NULL。 |
| PRIOR | 返回特定索引下标的前一个索引值(按照索引类型的排序规则排序)。 |
| NEXT | 返回特定索引下标的后一个索引值(按照索引类型的排序规则排序)。 |
示例
DECLARETYPE NumList IS TABLE OF NUMBER;numbers NumList := NumList(10, 20, 30, 40, 50);BEGIN-- 使用 COUNT 方法DBMS_OUTPUT.PUT_LINE('Count: ' || numbers.COUNT);-- 使用 EXISTS 方法IF numbers.EXISTS(3) THENDBMS_OUTPUT.PUT_LINE('Element 3 exists: ' || numbers(3));END IF;-- 使用 FIRST 和 LAST 方法DBMS_OUTPUT.PUT_LINE('First index: ' || numbers.FIRST);DBMS_OUTPUT.PUT_LINE('Last index: ' || numbers.LAST);-- 使用 PRIOR 和 NEXT 方法DBMS_OUTPUT.PUT_LINE('Prior to 3: ' || numbers.PRIOR(3));DBMS_OUTPUT.PUT_LINE('Next to 3: ' || numbers.NEXT(3));-- 使用 EXTEND 方法numbers.EXTEND(2);numbers(numbers.COUNT) := 60;DBMS_OUTPUT.PUT_LINE('After extend, Count: ' || numbers.COUNT);-- 使用 TRIM 方法numbers.TRIM(2);DBMS_OUTPUT.PUT_LINE('After trim, Count: ' || numbers.COUNT);-- 使用 DELETE 方法numbers.DELETE(3);DBMS_OUTPUT.PUT_LINE('After delete, Count: ' || numbers.COUNT);IF NOT numbers.EXISTS(3) THENDBMS_OUTPUT.PUT_LINE('Element 3 no longer exists');END IF;END;/
总结
HaloDB 对 Oracle 集合类型的支持让使用人员能够更有效地管理复杂的数据集。通过利用这些集合类型和方法可以:
实现高效的数据处理和临时存储。
提升数据库操作的灵活性和可扩展性。
通过集合方法简化对动态数据的管理。
这种支持使得 HaloDB 可以更好地满足企业级应用的复杂数据管理需求,提供了与 Oracle 相似的开发体验和功能集成。使用人员可以在 HaloDB 中应用这些集合类型来实现高效的数据操作和业务逻辑开发,进一步提升应用的性能和可维护性。




