--1 索引表 /* @下标无限制,可以为负数 @元素个数无限制 定义 TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY key_type; type_name:用户自定义数据类型的名字 element_type:索引表中元素类型 key_type:索引表元素下标的数据类型(BINARY_INTEGER,PLS_INTEGER,VARCHAR2) */
declare type index_tab_type is table of varchar2(30) index by BINARY_INTEGER; v_table index_tab_type; begin v_table(-1) :='hello';--设定下标为-1的元素的值 v_table(1) :=','; dbms_output.put_line(v_table(-1)||'-'||v_table(1)); dbms_output.put_line('元素个数:'||v_table.count); v_table(5) :='world'; dbms_output.put_line('元素个数:'||v_table.count); dbms_output.put_line('第一个元素'||v_table.first); dbms_output.put_line('最后一个元素'||v_table.last); end; /*输出结果 hello-, 元素个数:2 元素个数:3 第一个元素-1 最后一个元素5 */ --使用varchar2作为索引元素类型 ,其实也就和java中的map一样了 key-value形式存储 declare type index_tab_type is table of varchar2(30) index by varchar2(30); v_table index_tab_type; v_record emp%rowtype; begin --emp表中查询3条记录,以name-job的形式存储到索引表中 select * into v_record from emp where emp.empno=7788; v_table(v_record.ename):= v_record.job; select * into v_record from emp where emp.empno=7844; v_table(v_record.ename):= v_record.job; select * into v_record from emp where emp.empno=7900; v_table(v_record.ename):= v_record.job; dbms_output.put_line(v_table.count);--3 dbms_output.put_line(v_table(v_record.ename));--CLERK end;
--2嵌套表 NESTED TABLE /* 下标从1开始,元素个数灭有限制(*使用时必须先初始化,用extend属性可以扩展元素个数) 可以作为表定义数据类型,但是前提是要先create 创造嵌套表类型,这就可以实现1对多了 定义 TYPE type_name IS TABLE OF element_type; 和索引表的区别也就是看看有无index by语句,嵌套表的索引固定是int型的 */
declare type nest_table_type is table of emp.ename%type; v_nest_tab nest_table_type; begin v_nest_tab :=nest_table_type('x');--初始化 必须! 语句 type_name(...) select ename into v_nest_tab(1) from emp where empno=7788; dbms_output.put_line(v_nest_tab(1)); end;
declare type nest_tab_type is table of emp.ename%type; v_tab nest_tab_type; begin v_tab := nest_tab_type('x'); select ename into v_tab(1) from emp where emp.empno=7788; dbms_output.put_line(v_tab(1)); end;
--在表列中使用嵌套表 嵌套表类型的列是单独一个表存储 --先创建一个这样的类型 必须 才能使用 create type nest_tab_type is table of varchar2(30); create table test_nest_tab( id int, vals nest_tab_type --使用 ) nested table vals store as nest_tab;--vals字段用嵌套表存储,表明nest_tab --上面语句执行完之后,在生成TEST_NEST_TAB的同时会生出一个关联表NEST_TAB用来存储关联表的数据 --插入数据 insert into test_nest_tab values(1,nest_tab_type('one','two','three','four')); --查询数据 declare v_id int; v_tab nest_tab_type; begin select * into v_id,v_tab from test_nest_tab where id=1; dbms_output.put_line(v_id); for i in 1..v_tab.count loop dbms_output.put_line(v_tab(i)); end loop; end;
--3 VARRY 可变数组 变长数组 /* 定义 TYPE type_name IS VARRAY(size_limit) OF element_type[NOT NULL]; 这个就和java中的数组差不多了,下标from 1 ,定义时先指定最大元素个数,也和varchar2(size)这种一样。 使用时也必须先用构造方法初始化 可以作为表列类型 */ declare type varr is VARRAY(10) of int; v_varr varr :=varr(); begin --dbms_output.put_line(varr.count); for i in 1..5 loop v_varr.extend; v_varr(i) :=i*i; end loop;
for i in 1..5 loop dbms_output.put_line(v_varr(i)); end loop; end;
--可变数组作为表列类型 可变数组是存储在表内部的,不同于嵌套表 create type varr_type is varray(10) of varchar2(30);--先创建类型 create table test_varray( id int, name varchar2(30), params varr_type --param是使用可变数组类型 ); --插入数据 insert into test_varray values(1,'bird',varr_type('a','b','c')); --查询数据 declare v_varr varr_type; v_name test_varray.name%type; begin select name,params into v_name,v_varr from test_varray where id=1; for i in 1..v_varr.count loop dbms_output.put_line(v_varr(i)); end loop; end;
--记录表 集合类型是表的一行,集合元素不仅可以是简单类型,也可以是复合类型 declare type emp_tab_type is table of emp%rowtype index by binary_integer; v_tab emp_tab_type; begin select * into v_tab(1) from emp where emp.empno=7788; dbms_output.put_line(v_tab(1).ename||'-'||v_tab(1).job||'-'||v_tab(1).sal);--SCOTT-ANALYST-3000 end;
--集合方法综合使用例子 主要是遍历集合
declare type v_table_type is table of varchar2(30); v_table v_table_type :=v_table_type(); begin dbms_output.put_line(v_table.count||'-'||v_table.limit||'-'||v_table.first||'-'||v_table.last); -- 0--- if v_table.exists(1) then --判断index1是否有值 null; else v_table.extend;--扩充一个值 select ename into v_table(1) from emp where emp.empno=7788; dbms_output.put_line(v_table(1)); --SCOTT dbms_output.put_line(v_table.count||'-'||v_table.limit||'-'||v_table.first||'-'||v_table.last);-- 1--1-1 end if; end;
--遍历集合(不连续) declare type v_tab_type is table of varchar2(30) index by binary_integer; v_tab v_tab_type; v_index int; begin --添加几个无序有间隔的元素 v_tab(-1) :='a'; v_tab(2) :='b'; v_tab(3) :='c'; v_tab(5) :='d'; v_tab(-2) :='e'; --method 1 v_index :=v_tab.first; for i in 1..v_tab.count loop dbms_output.put_line(v_tab(v_index)); v_index :=v_tab.next(v_index); end loop; --method2 for i in v_tab.first..v_tab.last loop if v_tab.exists(i) then dbms_output.put_line(v_tab(i)); else dbms_output.put_line('元素不存在'); end if; end loop; end;
--修改集合中的元素 declare type v_tab_type is table of int; v_tab v_tab_type :=v_tab_type(); begin for i in 1..5 loop if v_tab.exists(i) then null; else v_tab.extend;--扩展一个 v_tab(i) := i*i; end if; end loop; dbms_output.put_line(v_tab.count);--5 for i in 1..5 loop dbms_output.put_line(v_tab(i)); if v_tab(i)=9 then --删除3*3=9的元素 v_tab.delete(i); end if; end loop; dbms_output.put_line(v_tab.count);--4 end;