文章目录

  • 集合
  • 1 联合数组
  • 语法格式
  • 2 嵌套表
  • 2.1 嵌套表初始化
  • 3 变长数组
  • 4 多层集合
  • 5 集合方法


集合

1 联合数组

也叫索引表,用于存储某个数据类型的数据的集合类型;可通过索引获得联合数组中的数据。

语法格式

type type_name is table of element_type [not null]
index by element_type;
table_name type_name;

实例:

SQL> l
  1  declare
  2     cursor my_cursor is
  3             select ename
  4                     from emp
  5             where sal<=2800;
  6     type ename_type is table of emp.ename%type --声明联合数组类型
  7             index by binary_integer;			--声明联合数组的索引
  						--(必须声明index by binary_integer,否则报错ORA-06531: 引用未初始化的收集)
  8     ename_table ename_type;						--声明ename_type的联合数组ename_type
  9     var_counter integer := 0;
 10     begin
 11             for ename_rec in my_cursor loop
 12                      var_counter  := var_counter + 1;
 13                     ename_table(var_counter) := ename_rec.ename;--循环游标将数据放入联合数组
 14                     dbms_output.put_line('ename ('||var_counter||'):'||ename_table(var_counter));
 15             end loop;
 16* end;
SQL> /
ename (1):SMITH
ename (2):ALLEN
ename (3):WARD
ename (4):MARTIN
ename (5):CLARK
ename (6):TURNER
ename (7):ADAMS
ename (8):JAMES
ename (9):MILLER

PL/SQL 过程已成功完成。

2 嵌套表

嵌套表与联合数组
区别:嵌套表可以存储在数据库表的列中,联合数组不可以;
相同点:具有相同结构,使用下标访问数据。
使用嵌套表必须先初始化才能使用
实例:

SQL> l
  1  declare
  2     cursor my_cursor is
  3             select ename
  4                     from emp
  5             where sal<=2800;
  6      type ename_type is table of emp.ename%type;
  7     ename_table ename_type;
  8     var_counter integer := 0;
  9     begin
 10             for ename_rec in my_cursor loop
 11                      var_counter  := var_counter + 1;
 12                     ename_table(var_counter) := ename_rec.ename;
 13                     dbms_output.put_line('ename ('||var_counter||'):'||ename_table(var_counter));
 14             end loop;
 15* end;
SQL> /
declare
*
第 1 行出现错误:
ORA-06531: 引用未初始化的收集
ORA-06512: 在 line 12

第6行代码 声明联合数组索引type ename_type is table of emp.ename%type index by binary_integer;后将不再报错;

2.1 嵌套表初始化

不过我们这里采用嵌套表的方式,type ename_type is table of emp.ename%type;声明嵌套表的元素类型后,ename_table ename_type := ename_type();

SQL> declare
  2     cursor my_cursor is
  3             select ename from emp
  4                     where sal<=2800;
  5     type ename_type is table of emp.ename%type;
  6     ename_table ename_type := ename_type();
  7     var_counter integer := 0;
  8  begin
  9     for ename_rec in my_cursor loop
 10             var_counter :=var_counter+1;
 11             
 12             ename_table(var_counter) := ename_rec.ename;
 13             dbms_output.put_line('ename('||var_counter||'):'||ename_table(var_counter));
 14     end loop;
 15  end;
 16  /
declare
*
第 1 行出现错误:
ORA-06533: 下标超出数量
ORA-06512: 在 line 12

显然光初始化还不够,嵌套表的集合需要调用 EXTEND 增加集合的大小;

extend 增加元素,只对嵌套表和数组,增加数组元素的时候,不能超过数组最大个数
extend --增加1个元素,元素值为null
extend(n) --增加n个元素,元素值为null
extend(n,i) --增加n个元素,元素值跟第i个元素值相同

SQL>  11             ename_table.extend;;
SQL> l
  1  declare
  2     cursor my_cursor is
  3             select ename from emp
  4                     where sal<=2800;
  5     type ename_type is table of emp.ename%type;
  6     ename_table ename_type := ename_type();
  7     var_counter integer :=0;
  8  begin
  9     for ename_rec in my_cursor loop
 10             var_counter :=var_counter+1;
 11              ename_table.extend;
 12             ename_table(var_counter) := ename_rec.ename;
 13             dbms_output.put_line('ename('||var_counter||'):'||ename_table(var_counter));
 14     end loop;
 15* end;
SQL> /
ename(1):SMITH
ename(2):ALLEN
ename(3):WARD
ename(4):MARTIN
ename(5):CLARK
ename(6):TURNER
ename(7):ADAMS
ename(8):JAMES
ename(9):MILLER

PL/SQL 过程已成功完成。

扩展延申

理解EXTEND用法:

sql server in 数组 sql 数组类型_数据结构

3 变长数组

declare var_counter integer :=0; 声明var_counter变量且赋值。(忘了语法了,做个记录)

  • 变长数组是一个集合类型,为每一个元素分配一个从1开始计数的下标,对应变长数组的位置。
  • 其尺寸受定义时的限制

实例:
创建一个变长数组其长度为10,

  1. 查看填充填充1~7位数据后的数据;
SQL> l
  1  declare
  2      type var_array_type is varray(10) of number(10);
  3     varray_array var_array_type := var_array_type();
  4     var_counter integer :=0;
  5  begin
  6     for i in 1..7 loop
  7             var_counter := var_counter+1;
  8             varray_array.extend;
  9             varray_array(var_counter) := i;
 10             dbms_output.put_line('varray_array('||i||')=='||varray_array(i));
 11     end loop;
 12
 13  for i in 1..10 loop
 14     dbms_output.put_line(varray_array(i));
 15     dbms_output.put_line('-----------');
 16  end loop;
 17* end;
SQL> /
varray_array(1)==1
varray_array(2)==2
varray_array(3)==3
varray_array(4)==4
varray_array(5)==5
varray_array(6)==6
varray_array(7)==7
1
-----------
2
-----------
3
-----------
4
-----------
5
-----------
6
-----------
7
-----------
declare
*
第 1 行出现错误:
ORA-06533: 下标超出数量
ORA-06512: 在 line 14
  1. 查看填充后三位的数据后以及删除后三位数据后的数据;
SQL> l
  1  declare
  2     type var_array_type is varray(10) of number(10);
  3     varray_array var_array_type := var_array_type();
  4     var_counter integer :=0;
  5  begin
  6     for i in 1..7 loop
  7     var_counter := var_counter + 1;
  8     varray_array.extend;
  9     varray_array(var_counter) :=i;
 10  end loop;
 11  dbms_output.put_line('varray_array.count ='||varray_array.count);#表示元素数量
 12  dbms_output.put_line('varray_array.first ='||varray_array.first);#表示第一个下标
 13  dbms_output.put_line('varray_array.last ='||varray_array.last);#最后一个下标,非元素值
 14  varray_array.extend(3,6);
 15   for i in 8..10 loop
 16  dbms_output.put_line('varray_array.('||i||') is '||varray_array(i));
 17  end loop;
 18  dbms_output.put_line('varray_array.last ='||varray_array.last);#最后一个下标,非元素值
 19  varray_array.trim(4);#删除后4个元素及下标
 20  dbms_output.put_line('varray_array.last ='||varray_array.last);#删除最后一个元素后的最后一个下标值
 21* end;
SQL> /
varray_array.count =7  #表示元素数量
varray_array.first =1  #表示第一个下标
varray_array.last =7   #最后一个下标,非元素值
varray_array.(8) is 6
varray_array.(9) is 6
varray_array.(10) is 6
varray_array.last =10
varray_array.last =6#删除最后一个元素后的最后一个下标值

PL/SQL 过程已成功完成。

【为什么不用python数组搞这些呢?疑惑😮】

4 多层集合

  • 集合的集合,即集合作为集合的元素

实例:
创建一个三层变长数组集合,变长数组元素类型为INTEGER

SQL> l
  1  declare
  #声明变长数组var_tye1
  2  type var_tye1 is  varray(5) of integer;
  #声明多层集合,集合元素类型为var_tye1
  3  type var_tye2 is  varray(3) of var_tye1;
  #声明变长数组变量
  4  varray_integer var_tye1 := var_tye1(1,2,3,4,5);
  #声明多层集合varray_multi,并向其填充变长数组varray_integer来赋初值
  5  varray_multi var_tye2 := var_tye2(varray_integer);
  6
  7  begin
  8     dbms_output.put_line('varray_integer value : ');
  9  for i in 1..5 loop
 10      dbms_output.put_line('varray_integer('||i||') is: '||varray_integer(i));
 11  end loop;
 #填充数据时需先扩展多层集合再赋值
 12  varray_multi.extend;
 13  varray_multi(2) := var_tye1(6,7,8,9,10);
 14  varray_multi.extend;
 15  varray_multi(3) := var_tye1(5,4,3,2,1);
 16  for i in 1..3 loop
 17     for j in 1..5 loop
 18             dbms_output.put_line
 19                     ('varray_multi['||i||']'||'['||j||'] is : ' || varray_multi(i)(j));
 20     end loop;
 21  end loop;
 22* end;
SQL> /
varray_integer value :
varray_integer(1) is: 1
varray_integer(2) is: 2
varray_integer(3) is: 3
varray_integer(4) is: 4
varray_integer(5) is: 5
varray_multi[1][1] is : 1
varray_multi[1][2] is : 2
varray_multi[1][3] is : 3
varray_multi[1][4] is : 4
varray_multi[1][5] is : 5
varray_multi[2][1] is : 6
varray_multi[2][2] is : 7
varray_multi[2][3] is : 8
varray_multi[2][4] is : 9
varray_multi[2][5] is : 10
varray_multi[3][1] is : 5
varray_multi[3][2] is : 4
varray_multi[3][3] is : 3
varray_multi[3][4] is : 2
varray_multi[3][5] is : 1

PL/SQL 过程已成功完成。

示意图如下:

sql server in 数组 sql 数组类型_数组_02

5 集合方法

  • delete:删除集合元素
  • extend:为集合增加元素空间,实现空间的的扩展以及填充新的元素
  • count:集合中的元素数量
  • exists:如果指定的元素在集合中存在,则返回TRUE
  • delete:删除集合指定位置的元素
  • first and last:返回集合的第一个和最后一个元素
  • prior and next :返回集合指定元素的前一个和后一个元素
  • trim:从集合尾部删除元素
  • limit:但会集合允许的元素的最大数量
SQL> l
  1  declare
  2     type asso_array_type is table of number
  3             index by binary_integer;
  4             asso_array_tab asso_array_type;
  5  begin
  6     for i in 1..20 loop
  7             asso_array_tab(i) :=i;
  8     end loop;
  9  dbms_output.put_line('asso_array_tab.count '||asso_array_tab.count);
 10  asso_array_tab.delete(20);#删除了联合数组第20位的数据(同时删除了占位符)
 11  dbms_output.put_line('asso_array_tab.count '||asso_array_tab.count);
 12  dbms_output.put_line('asso_array_tab.last '||asso_array_tab.last);
 13  asso_array_tab.delete(1,5);#删除了从1~5的联合数组占位符中的数值
 14  dbms_output.put_line('asso_array_tab.count '||asso_array_tab.count);
 15  dbms_output.put_line('asso_array_tab.first '||asso_array_tab.first);
 16  if asso_array_tab.exists(17) then #判断联合数组第17位的元素是否存在
 17  dbms_output.put_line('asso_array_tab.exists(17) is  '||asso_array_tab(17));
 18  end if;
 19   dbms_output.put_line('asso_array_tab.prior(5) is  '||asso_array_tab.prior(5));
 20   dbms_output.put_line('asso_array_tab.next(5) is  '||asso_array_tab.next(5));
 21* end;
SQL> /
asso_array_tab.count 20
asso_array_tab.count 19
asso_array_tab.last 19
asso_array_tab.count 14
asso_array_tab.first 6
asso_array_tab.exists(17) is  17
asso_array_tab.prior(5) is   #因为删除了联合数组1~5位的元素,所以返回第五位前面的数据是NULL
asso_array_tab.next(5) is  6

PL/SQL 过程已成功完成。