ORACLE 集合(关联数组,嵌套表,VARRAY)
2014年10月25日 19:27:22 vampireslove 阅读数:835 标签: plsql 更多
个人分类: ORACLE
元素下标 | 个数限制 | 初始化 | 表数据列 | |
索引表 | (binary_integer、pls_integer、varchar2) | 无限制 | 不需要 | 不可以 |
嵌套表 | 从1开始 | 无限制 | 需要 | 可以 |
数组 | 从1开始 | 有最大个数 | 需要 | 可以 |
1.索引表
type type_name is table of element_type[not null] index by key_type;
type_name 自定义数据类型的名称
is table .. index 表示索引表
element_type 索引表元素的数据类型
not null 表示不请允许引用null元素
key_type(binary_integer、pls_integer、varchar2) 索引表元素下标的数据类型,注意9i前只能用binary_integer、pls_integer
元素下标可以负值,元素大小个数没有限制
- set serveroutput on;
- declare
- type ename_table_type is table of emp.ename%type index by binary_integer;
- ename_table ename_table_type;
- begin
- select ename into ename_table(-1) from emp where empno = 7788;
- dbms_output.put_line('雇员名:' || ename_table(-1));
- end;
- /
- 雇员名:SCOTT
- PL/SQL procedure successfully completed
2.嵌套表
type type_name is table of element_type;
元素下标从1开始,元素个数没有限制,数组元素值可以稀疏
使用嵌套表元素时,必须首先使用其构造方法初始化嵌套表
- set serveroutput on;
- declare
- type ename_table_type is table of emp.ename%type;
- ename_table ename_table_type;
- begin
- ename_table:=ename_table_type('A','A');
- select ename into ename_table(2) from emp where empno = 7788;
- dbms_output.put_line('雇员名:' || ename_table(2));
- end;
- /
- 雇员名:SCOTT
- PL/SQL procedure successfully completed
嵌套表还可以作为表列的数据类型使用
- create type phone_type is table of varchar2(20);
- /
- create table employee(
- id number(4),name varchar2(10),sal number(6,2) ,phone phone_type
- )nested table phone store as phone_table;
- /
- --insert
- insert into employee
- values
- (1, 'scott', 800, phone_type('123456', '789012'));
- commit;
- --select
- declare
- phone_table phone_type;
- begin
- select phone into phone_table from employee where id=1;
- for i in 1..phone_table.count loop
- dbms_output.put_line('电话号码:'||phone_table(i));
- end loop;
- end;
- /
- 电话号码:123456
- 电话号码:789012
- PL/SQL procedure successfully completed
- --update
- declare
- phone_table phone_type:=phone_type('11','22','33');
- begin
- update employee set phone=phone_table where id=1;
- commit;
- end;
- /
3.变长数组varray
type type_name is varray(size_limit) of element_type[not null];
size_limit 指定varray元素的最大个数
元素下标从1开始,最大元素有限制,可以当作表数据列
使用前,必须要使用构造方法初始化varray元素
- declare
- type ename_table_type is varray(10) of emp.ename%type;--元素最大个数定义后不可改变
- ename_table ename_table_type := ename_table_type('A','B');--初始化两个元素,可以通过ename_table.extend方法添加元素,默认为null,不能超过最大个数
- begin
- select ename into ename_table(1) from emp where empno=7788; --下标从1开始,没有初始的不能直接使用,如ename_table(3)错
- dbms_output.put_line(ename_table(1));
- end;
- /
- SCOTT
- PL/SQL procedure successfully completed
在表列中使用varray
- create type phone_type is varray(10) of varchar2(20);
- /
- create table employee(
- id number(4),name varchar2(10),sal number(6,2),phone phone_type
- );
- /
- --操作跟嵌套表列一样,元素个数有限制
https://blog.csdn.net/VampiresLove/article/details/40455505
Oracle复合类型:嵌套表、可变数组与索引表
2017年02月24日 11:04:13 花公子丶 阅读数:567
一、 在pl/sql中使用嵌套表和可变数组
1、在pl/sql中使用嵌套表
在PL/SQL中使用嵌套表,此时嵌套表就相当于其他语言中的数组。
①、示例:
<span style="color:#000000"><code><span style="color:#000088 !important">set</span> SERVEROUTPUT <span style="color:#000088 !important">ON</span>
<span style="color:#000088 !important">DECLARE</span>
--下面这句是嵌套表声明的
TYPE ename_array_type <span style="color:#000088 !important">is</span> <span style="color:#000088 !important">table</span> <span style="color:#000088 !important">of</span> emp.ename%TYPE ;
<span style="color:#880000 !important"><em>--定义一个游标</em></span>
CURSOR ename_cursor is <span style="color:#000088 !important">select</span> ename <span style="color:#000088 !important">from</span> emp <span style="color:#000088 !important">where</span> job=<span style="color:#009900 !important">'CLERK'</span>;
<span style="color:#880000 !important"><em>--初始化嵌套表,此时嵌套表为空</em></span>
ename_arrayename_array_type:=ename_array_type();
i number:=0;
<span style="color:#000088 !important">BEGIN</span>
forename <span style="color:#000088 !important">in</span> ename_cursor
loop
i:=i+<span style="color:#006666 !important">1</span>;
<span style="color:#880000 !important"><em>--执行extend函数,为数组增加一个null元素</em></span>
ename_array.EXTEND;
ename_array(i):=ename.ename;
DBMS_OUTPUT.PUT_LINE(ename.ename);
<span style="color:#000088 !important">end</span> loop;
<span style="color:#880000 !important"><em>--嵌套表下标是从1开始的,而不是0</em></span>
DBMS_OUTPUT.PUT_LINE('嵌套表:'||ename_array(1)||' '|| ename_array(2));
<span style="color:#000088 !important">END</span>;
/</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
②、嵌套表声明:
TYPE type_name is table of 表元素类型。例如:
<span style="color:#000000"><code><span style="color:#000088 !important">TYPE</span> ename_array_type <span style="color:#000088 !important">is</span> table <span style="color:#000088 !important">of</span> emp.ename%<span style="color:#000088 !important">TYPE</span> ;</code></span>
- 1
③、嵌套表初始化:
嵌套表必须初始化后才能使用,初始化方式有两种,
一种是初始化为空,例如上面例子中
<span style="color:#000000"><code>ename_arrayename_array_<span style="color:#4f4f4f !important">type</span>:=ename_array_<span style="color:#4f4f4f !important">type</span>();</code></span>
- 1
由于ename_array被初始化为空,所以如果需要往里面放数据,就
需要为其增加一个元素,否则将会报错。EXTEND就是用来为数组增加元素的,例如上面例子中:
ename_array.EXTEND;
另一种是初始化时直接为数组分配元素,
如:ename_array:=ename_array_type(‘草泥马’,’草泥马’);
此时ename_array(1)和ename_array(2)的值为草泥马。这时候也可以直接为ename_array(1)和ename_array(2)赋值,如
<span style="color:#000000"><code>ename_array(<span style="color:#006666 !important">1</span>):=<span style="color:#009900 !important">'羊驼'</span>;
ename_array(<span style="color:#006666 !important">2</span>):=<span style="color:#009900 !important">'红色羊驼'</span>;</code></span>
- 1
- 2
但是如果想为第三个元素赋值,需要先执行:ename_array.EXTEND。
因为在初始化的时候,只为数组分配了两个元素,所以想给第三
个元素赋值就必须先为数组分配一个元素。
2、在pl/sql中使用可变数组
①、示例:
<span style="color:#000000"><code><span style="color:#000088 !important">set</span> SERVEROUTPUT <span style="color:#000088 !important">ON</span>
<span style="color:#000088 !important">DECLARE</span>
--这个例子跟上面基本一样,只是下面这句原本<span style="color:#000088 !important">is</span> <span style="color:#000088 !important">table</span>变成<span style="color:#000088 !important">is</span> varray(<span style="color:#006666 !important">5</span>)
TYPE ename_array_type <span style="color:#000088 !important">is</span> VARRAY(<span style="color:#006666 !important">4</span>) <span style="color:#000088 !important">of</span> emp.ename%TYPE ;
CURSOR ename_cursor is <span style="color:#000088 !important">select</span> ename <span style="color:#000088 !important">from</span> emp <span style="color:#000088 !important">where</span> job=<span style="color:#009900 !important">'CLERK'</span>;
ename_arrayename_array_type:=ename_array_type();
i number:=0;
<span style="color:#000088 !important">BEGIN</span>
forename <span style="color:#000088 !important">in</span> ename_cursor
loop
i:=i+<span style="color:#006666 !important">1</span>;
ename_array.EXTEND;
ename_array(i):=ename.ename;
DBMS_OUTPUT.PUT_LINE(ename.ename);
<span style="color:#000088 !important">end</span> loop;
<span style="color:#880000 !important"><em>--下标也是从1开始的,而不是0</em></span>
DBMS_OUTPUT.PUT_LINE('嵌套表:'||ename_array(1)||' '|| ename_array(2));
<span style="color:#000088 !important">END</span>;
/</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
②、可变数组声明
TYPE type_name is varray(数组元素个数) of 表元素类型。例如:
<span style="color:#000000"><code><span style="color:#000088 !important">TYPE</span> ename_array_type <span style="color:#000088 !important">is</span> VARRAY(<span style="color:#006666 !important">4</span>) <span style="color:#000088 !important">of</span> emp.ename%<span style="color:#000088 !important">TYPE</span> ;</code></span>
- 1
由于ename_array_type被声明为VARRAY(4),这说明ename_array_type类
型的数组,最多只能放4个元素。如果想为第5个元素赋值,将会报错,即
ename_array(5):=’hello’,此时将会报错,即使在赋值前调用EXTEND:
ename_array.EXTEND也依然会报错。
3、在pl/sql中使用嵌套表和可用数组的区别
在PL/SQL中使用嵌套表和可变数组,基本是一样的,唯一的不同是,可变数
组的元素个数是有限制的,而嵌套表没有元素个数的限制
二、 在表列中使用嵌套表和可变数组(面向对象的SQL)
1、在表列中使用嵌套表
示例:
①、创建对象
<span style="color:#000000"><code><span style="color:#000088 !important">create</span> <span style="color:#000088 !important">or</span> <span style="color:#000088 !important">replace</span> TYPE comm_info <span style="color:#000088 !important">AS</span> OBJECT ( /*此类型为通讯方式的集合*/
<span style="color:#000088 !important">no</span> <span style="color:#000088 !important">number</span>(<span style="color:#006666 !important">3</span>), /*通讯类型号*/
comm_type varchar2(<span style="color:#006666 !important">20</span>), /*通讯类型*/
comm_no varchar2(<span style="color:#006666 !important">30</span>)/*号码*/
);</code></span>
- 1
- 2
- 3
- 4
- 5
②、创建嵌套表
<span style="color:#000000"><code><span style="color:#000088 !important">create</span> <span style="color:#000088 !important">or</span> <span style="color:#000088 !important">replace</span> TYPE comm_info_list <span style="color:#000088 !important">AS</span> <span style="color:#000088 !important">table</span> <span style="color:#000088 !important">OF</span> comm_info;</code></span>
- 1
③、创建表
<span style="color:#000000"><code><span style="color:#000088 !important">create</span> <span style="color:#000088 !important">table</span> user_info(
user_id <span style="color:#000088 !important">number</span>(<span style="color:#006666 !important">6</span>), /*用户ID号*/
user_name varchar2(<span style="color:#006666 !important">20</span>), /*用户名称*/
user_comm comm_info_list /*与用户联系的通讯方式*/
)--下面这句的意思是把user_comm的数据放到user_comm_table表中存储
nested <span style="color:#000088 !important">table</span> user_comm store <span style="color:#000088 !important">as</span> user_comm_table;</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
执行命令后,你会发现你创建了两张表,一张是user_info,一张是嵌套表
user_comm_table
④、插入数据
<span style="color:#000000"><code><span style="color:#000088 !important">insert</span> <span style="color:#000088 !important">into</span> user_info
<span style="color:#000088 !important">values</span>(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'mary'</span>,comm_info_list(
comm_info(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'手机'</span>,<span style="color:#009900 !important">'13651401919'</span>),
comm_info(<span style="color:#006666 !important">2</span>,<span style="color:#009900 !important">'呼机'</span>,<span style="color:#009900 !important">'1281234567'</span>)
)
);
<span style="color:#000088 !important">insert</span> <span style="color:#000088 !important">into</span> user_info
<span style="color:#000088 !important">values</span>(<span style="color:#006666 !important">2</span>,<span style="color:#009900 !important">'carl'</span>,comm_info_list(
comm_info(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'手机'</span>,<span style="color:#009900 !important">'13901018888'</span>),
comm_info(<span style="color:#006666 !important">2</span>,<span style="color:#009900 !important">'呼机'</span>,<span style="color:#009900 !important">'1281234567'</span>)
)
);</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
⑤、查询嵌套表
通过user_info查询其嵌套表信息,此时注意括号内的查询,只能查询一列,即可以select user_comm而不能select user_comm,user_name,并且只能返回一条记录,否则会报错
<span style="color:#000000"><code>selectcomm_type,comm_nofrom table(
<span style="color:#000088 !important">select</span> user_comm <span style="color:#000088 !important">from</span> user_info <span style="color:#000088 !important">where</span> user_id=<span style="color:#006666 !important">1</span>
);
执行结果如下:
COMM_TYPE COMM_NO
<span style="color:#880000 !important"><em>-------------------- ------------------------------</em></span>
手机 13651401919
呼机 1281234567 </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如果不查询具体的嵌套表信息,则没有只能查询一列并且只能返回一条记录的限制,但是好像获取的信息不那么有用:
<span style="color:#000000"><code><span style="color:#000088 !important">select</span> user_comm <span style="color:#000088 !important">from</span> user_info;
执行如下:
-------------------------------------------------------------------------------------------------------
SCOTT.COMM_INFO_LIST(
SCOTT.COMM_INFO(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'手机'</span>,<span style="color:#009900 !important">'13651401919'</span>),
SCOTT.COMM_INFO(<span style="color:#006666 !important">2</span>,<span style="color:#009900 !important">'呼机'</span>,<span style="color:#009900 !important">'1281234567'</span>)
)
SCOTT.COMM_INFO_LIST(
SCOTT.COMM_INFO(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'手机'</span>,<span style="color:#009900 !important">'13901018888'</span>),
SCOTT.COMM_INFO(<span style="color:#006666 !important">2</span>,<span style="color:#009900 !important">'呼机'</span>,<span style="color:#009900 !important">'1281234567'</span>)
) </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2、在表列中使用可变数组
示例:
①、创建对象
<span style="color:#000000"><code><span style="color:#000088 !important">create</span> <span style="color:#000088 !important">or</span> <span style="color:#000088 !important">replace</span> TYPE comm_info <span style="color:#000088 !important">AS</span> OBJECT ( /*此类型为通讯方式的集合*/
<span style="color:#000088 !important">no</span> <span style="color:#000088 !important">number</span>(<span style="color:#006666 !important">3</span>), /*通讯类型号*/
comm_type varchar2(<span style="color:#006666 !important">20</span>), /*通讯类型*/
comm_no varchar2(<span style="color:#006666 !important">30</span>)/*号码*/
);</code></span>
- 1
- 2
- 3
- 4
- 5
②、创建可变数组
<span style="color:#000000"><code><span style="color:#000088 !important">create</span> <span style="color:#000088 !important">or</span> <span style="color:#000088 !important">replace</span> TYPE comm_info_list <span style="color:#000088 !important">AS</span> varray(<span style="color:#006666 !important">50</span>) <span style="color:#000088 !important">OF</span> comm_info;</code></span>
- 1
③、创建表
<span style="color:#000000"><code><span style="color:#4f4f4f !important">create</span> table user_info(
user_id <span style="color:#4f4f4f !important">number</span>(<span style="color:#006666 !important">6</span>), <span style="color:#880000 !important"><em>/*用户ID号*/</em></span>
user_name varchar2(<span style="color:#006666 !important">20</span>), <span style="color:#880000 !important"><em>/*用户名称*/</em></span>
user_comm comm_info_list <span style="color:#880000 !important"><em>/*与用户联系的通讯方式*/</em></span>
)</code></span>
- 1
- 2
- 3
- 4
- 5
至于数据插入,和查询,就跟嵌套表的是一模一样。
3、在表列中使用嵌套表和可变数组的区别
第一个区别是:创建表的时候不一样,嵌套表创建时需要加这句
nested table user_comm store as user_comm_table,并且执行创建表语句后,
会产生两张表,其中一张是嵌套表,嵌套表类型的信息就放在嵌套表里。而
可变数组不需要加这句话,所以创建表的语句显得比较简单,而且执行创建
后,只会创建一张表。
第二个区别:
可变数组是有元素个数的限制的,比如
create or replace TYPE comm_info_list AS varray(50) OF comm_info;
则comm_info_list类型的数组最多只能放50个元素,即插入的时候,
<span style="color:#000000"><code><span style="color:#000088 !important">insert</span> <span style="color:#000088 !important">into</span> user_info
<span style="color:#000088 !important">values</span>(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'mary'</span>,comm_info_list(
comm_info(<span style="color:#006666 !important">1</span>,<span style="color:#009900 !important">'手机'</span>,<span style="color:#009900 !important">'13651401919'</span>),
comm_info(<span style="color:#006666 !important">2</span>,<span style="color:#009900 !important">'呼机'</span>,<span style="color:#009900 !important">'1281234567'</span>)
)
);</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
括号内的comm_info最多只能放50个,上面放了两个,分别是
comm_info(1,’手机’,’13651401919’)和 comm_info(2,’呼机’,’1281234567’)
而嵌套表没有这个限制。
三、 索引表(index by)
索引表只能用于PL/SQL中。在前面PL/SQL中使用嵌套表,其声明是:
TYPE ename_array_type is table of emp.ename%TYPE ;
而把这个声明改为index by就成了索引表,即:
TYPE ename_array_type is table of emp.ename%TYPE index by binary_integer ;
binary_integer后面也可以跟其他PL/SQL支持的类型,比如index by varchar2
虽然索引表跟嵌套表很像,但是嵌套表像数组,而索引表更像key-value映射的map
而index by后面的就是key的数据类型。
1、索引表使用示例:
<span style="color:#000000"><code><span style="color:#000088 !important">set</span> SERVEROUTPUT <span style="color:#000088 !important">ON</span>
<span style="color:#000088 !important">DECLARE</span>
TYPE ename_array_type <span style="color:#000088 !important">is</span> <span style="color:#000088 !important">table</span> <span style="color:#000088 !important">of</span> emp.ename%TYPE index <span style="color:#000088 !important">by</span> BINARY_INTEGER;
CURSOR ename_cursor is <span style="color:#000088 !important">select</span> ename <span style="color:#000088 !important">from</span> emp <span style="color:#000088 !important">where</span> job=<span style="color:#009900 !important">'CLERK'</span>;
ename_array ename_array_type;<span style="color:#880000 !important"><em>--这里直接定义就行,初始化都不用了</em></span>
i BINARY_INTEGER:=0;
<span style="color:#000088 !important">BEGIN</span>
<span style="color:#000088 !important">for</span> ename <span style="color:#000088 !important">in</span> ename_cursor
loop
-- ename_array.EXTEND;这句被注释起来了
ename_array(i):=ename.ename;
DBMS_OUTPUT.PUT_LINE(ename.ename);
i:=i+1;
<span style="color:#000088 !important">end</span> loop;
<span style="color:#880000 !important"><em>--下标从0开始</em></span>
DBMS_OUTPUT.PUT_LINE('嵌套表:'||ename_array(0)||' '|| ename_array(1));
<span style="color:#000088 !important">end</span>;
/</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
可以看到使用在PL/SQL中使用索引表会比使用嵌套表和可变数组简单很多。
2、索引表作为map的使用示例
前面说索引表更像是map,为什么这么说,可以看下面的例子:
<span style="color:#000000"><code><span style="color:#000088 !important">set</span> SERVEROUTPUT <span style="color:#000088 !important">ON</span>
declare
<span style="color:#000088 !important">type</span> map_type <span style="color:#000088 !important">is</span> table <span style="color:#000088 !important">of</span> number(<span style="color:#006666 !important">3</span>) <span style="color:#000088 !important">index</span> <span style="color:#000088 !important">by</span> varchar2(<span style="color:#006666 !important">3</span>);
map_ map_type;
map_key varchar2(<span style="color:#006666 !important">3</span>);
<span style="color:#000088 !important">begin</span>
map_ (<span style="color:#009900 !important">'a'</span>) := <span style="color:#006666 !important">10</span>;
map_ (<span style="color:#009900 !important">'b'</span>) := <span style="color:#006666 !important">20</span>;
map_key :=map_ .first;
<span style="color:#000088 !important">while</span>(map_key <span style="color:#000088 !important">is</span> <span style="color:#000088 !important">not</span> null) <span style="color:#000088 !important">loop</span>
dbms_output.put_line(map_ (map_key));
map_key:=map_ .next(map_key);
<span style="color:#000088 !important">end</span> <span style="color:#000088 !important">loop</span>;
<span style="color:#000088 !important">end</span>;
/</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
四、 嵌套表,可变数组与索引表的区别
嵌套表与可变数组的区别是,嵌套表没有元素个数的限制,而可变数组有元素个数的限制。嵌套表和可变数组与索引表的区别是,嵌套表和可变数组可以用于非PL/SQL环境,而索引表只能用于PL/SQL中。
五、 相关函数
1、COUNT 返回集合中元素的个数
2、删除集合元素DELETE,DELETE(x),DELETE(x,y),TRIM,TRIM(x)
DELETE删除集合中所有元素
DELETE(x) 删除元素下标为x的元素,如果x为null,则集合保持不变 对VARRAY
非法
DELETE(x,y) 删除元素下标从X到Y的元素,如果X>Y集合保持不变 对VARRAY
非法
TRIM 从集合末端开始删除一个元素 对index_by不合法
TRIM(x) 从集合末端开始删除x个元素 对index_by不合法
3、判断元素是否存在EXIST(x)
如果集合元素x已经初始化,则返回TRUE, 否则返回FALSE
4、为集合添加元素EXTEND,EXTEND(x),EXTEND(x,n)
EXTEND 在集合末尾添加一个元素 对Index_by非法
EXTEND(x) 在集合末尾添加x个元素 对Index_by非法
EXTEND(x,n) 在集合末尾添加元素n的x个副本 对Index_by非法
5、返回集合元素下标FIRST、LAST、NEXT(x),PRIOR(x)
FIRST 返回集合中的第一个元素的下标号,对于VARRAY集合始终返回1。
LAST 返回集合中最后一个元素的下标号, 对于VARRAY返回值始终等于COUNT。
NEXT(x) 返回在元素x之后及紧挨着它的元素的下标值,如果该元素是最后一
个元素,则返回null。
PRIOR(x) 返回集合中在元素x之前紧挨着它的元素的下标值,如果该元素是第
一个元素,则返回null。
6、LIMIT 返回VARRY集合的最大的元素个数,对于嵌套表和Index_by集合无用。
https://blog.csdn.net/yu766588220/article/details/56834930
Oracle集合(联合数组(索引表),嵌套表,变长数组,记录类型的嵌套表)的初始化与赋值,以及它们的区别
2017年11月30日 22:17:01 eussi 阅读数:444 标签: oracle集合 更多
个人分类: ◆◇乀 ≡ oracle related
Oracle集合(联合数组(索引表),嵌套表,变长数组,记录类型的嵌套表)的初始化与赋值,以及它们的区别
--其中嵌套表与变长数组在赋值之前必须初始化,可以使用与集合类型同名的函数来进行初始化,
联合数组无需初始化 www.2cto.com
--1.联合数组:
DECLARE
TYPE ind_tab_type IS TABLE OF VARCHAR2(2000)
INDEX BY BINARY_INTEGER;
ind_tab ind_tab_type;
BEGIN
ind_tab(1) := 'lubinsu';--这里的下标可以随意指定,可以通过循环来获取
ind_tab(2) := 'luzhou';
--dbms_output.put_line(ind_tab(0));
--dbms_output.put_line(ind_tab(1));
FOR i IN ind_tab.first..ind_tab.last LOOP
dbms_output.put_line('ind_tab(' || i || '):' || ind_tab(i));
END LOOP;
END;
/
--2.嵌套表的初始化1
--嵌套表的下标默认为1开始,也可以自己指定任意值 www.2cto.com
DECLARE
TYPE nest_tab_type IS TABLE OF VARCHAR2(2000) NOT NULL; --如果设置not null条件那么在初始化的时候不可以设置null
nest_tab nest_tab_type := nest_tab_type('lubinsu', 'luzhou'); --初始化的时候只要在集合变量之后使用空的构造函数或者直接赋值即可
BEGIN
FOR i IN nest_tab.first .. nest_tab.last LOOP
dbms_output.put_line('nest_tab(' || i || ') value is ' || nest_tab(i));
END LOOP;
END;
/
--3.嵌套表和的初始化2
DECLARE
TYPE nest_tab_type IS TABLE OF VARCHAR2(2000) NOT NULL; --如果设置not null条件那么在初始化的时候不可以设置null
nest_tab nest_tab_type := nest_tab_type(); --初始化的时候只要在集合变量之后使用空的构造函数或者直接赋值即可
BEGIN
nest_tab.extend;
nest_tab(1) := 'lubinsu';
nest_tab.extend;
nest_tab(2) := 'luzhou';
FOR i IN nest_tab.first .. nest_tab.last LOOP
dbms_output.put_line('nest_tab(' || i || '):' || nest_tab(i));
END LOOP;
END;
/
--如果设置not null条件那么在初始化的时候不可以设置null,如:nest_tab(1) := null;否则出错提示;
ORA-06550: line 7, column 18:
PLS-00382: expression is of wrong type
ORA-06550: line 7, column 3:
PL/SQL: Statement ignored
--赋值的时候必须使用extend来扩展集合的容量否则会如下错误
ERROR at line 1:
ora-06533: subscript beyond count
ora-06512: at line 6
/
--4.变长数组类似于PL/SQL表,每个元素都被分配了一个连续的下标,从1开始
--4.变长数组的初始化(与嵌套表的初始化方式一样)
DECLARE
TYPE varray_tab_type IS VARRAY(10) OF VARCHAR2(2000);
varray_tab varray_tab_type := varray_tab_type('lubinsu', 'luzhou'); --初始化的时候只要在集合变量之后使用空的构造函数或者直接赋值即可
BEGIN
varray_tab.extend;
varray_tab(3) := 'zengq';
varray_tab.extend;
varray_tab(4) := 'buwei';
FOR i IN varray_tab.first .. varray_tab.last LOOP
dbms_output.put_line('varray_tab(' || i || '):' || varray_tab(i));
END LOOP;
END;
/
--5.集合与集合之间的赋值必须是相同的TYPE
DECLARE
TYPE type1 IS TABLE OF NUMBER(2);
TYPE type2 IS TABLE OF NUMBER(2);
type1_tab type1 := type1(1, 2, 3);
type1_tab2 type1 := type1(4, 5, 6);
type2_tab type2 := type2(3, 2, 1);
BEGIN
type1_tab2 := type1_tab;
--type1_tab2 := type2_tab; 不可用
FOR i IN type1_tab2.first .. type1_tab2.last LOOP
dbms_output.put_line('type1_tab2(' || i || '):' || type1_tab2(i));
END LOOP;
END;
/
--type1_tab2 := type2_tab;报错
ORA-06550: line 10, column 17:
PLS-00382: expression is of wrong type
ORA-06550: line 10, column 3:
PL/SQL: Statement ignored
RESULT:
type1_tab2(1):1
type1_tab2(2):2
type1_tab2(3):3
/
--6.使用null值为集合赋值
DECLARE
TYPE type1 IS TABLE OF NUMBER(2);
type1_tab type1 := type1();--已经初始化,不为空,虽然没有赋值
type1_tab2 type1;--未初始化,为空
BEGIN
IF type1_tab IS NOT NULL THEN
dbms_output.put_line('type1_tab is not null');
END IF;
--type1_tab := NULL;
--或者
type1_tab := type1_tab2;
IF type1_tab IS NULL THEN
dbms_output.put_line('type1_tab is null');
END IF;
END;
/
--7.超出变长数组长度的值将会被丢弃 www.2cto.com
--8.记录类型的嵌套表的初始化,赋值以及元素的引用
DECLARE
TYPE object_rec IS RECORD(
object_id all_objects_loc.object_id%TYPE,
object_name all_objects_loc.object_name%TYPE,
object_type all_objects_loc.object_type%TYPE);
TYPE object_tab_type IS TABLE OF object_rec;
object_tab object_tab_type;
TYPE obj_cur_type IS REF CURSOR; --声明游标变量类型
obj_cur obj_cur_type;
BEGIN
OPEN obj_cur FOR
SELECT a.object_id, a.object_name, a.object_type
FROM all_objects_loc a
WHERE rownum <= 10;
FETCH obj_cur BULK COLLECT
INTO object_tab;
CLOSE obj_cur;
FOR i IN 1 .. object_tab.count LOOP
dbms_output.put_line('object_tab(' || i || '):' || object_tab(i)
.object_id || ',' || object_tab(i).object_name || ',' || object_tab(i)
.object_type);
END LOOP;
END;
/