所谓集合是一种类似于列表或者一维数组的数据结构。PL/SQL提供了三种集合类型:关联数据组(索引表),嵌套表和VARRAY(可变长数组)。
1.集合类型
1.1关联数组
关联数组(也称为索引表)是一组键值对。每个密钥都是唯一的,并且被用于定位相应的值。键可以是整数或字符串。只能用于PL/SQL环境。
1.2嵌套表
从概念上讲,嵌套表像一个元素数量任意的一维数组。
在数据库中,嵌套表是存储一组值的列类型,数据库存储嵌套表的行是没有特定顺序的。当你从数据中提取嵌套表到PL/SQL变量时,该行给出连续从1开始的下标。通过这些类似数组下标访问独立的行。
嵌套表不同于数组的重要方面:
- 数组需要声明元素的个数,而嵌套表不需要。嵌套表的大小可以动态增加。
- 数组总是密集的,嵌套表刚开始是密集的,但是后面有可能会变成稀疏的。因为你会从嵌套表中删除元素。
1.3 可变长的数组
可变长的数组是一个VARRAY数据类型的集合。当你声明VARRAY类型的时候,就必须指定同时指定它能够包含的最大元素个数。VARRAY可以包含可变数据的元素,从零到最大值。VARRAY索引有一个固定定的下限1和一个可扩展的上限。和嵌套表类型一样的是,它们都可以用于PL/SQL和数据库。但是和嵌套表不一样的是,在向VARRAY中保存数据或者提取数据时,它的元素是有序的。
2.声明集合类型
在使用一个集合之前,我们必须先声明它。有两种方法可以申明一个集合类型:
- 通过TYPE语句在一个PL/SQL程序中声明集合类型。
- 通过CREATE TYPE语句在数据中定义一个嵌套表或者VARRAY类型,这个类型就是一个模式级别的对象。这种类型就可以用作数据库表的列的数据类型,可以用作对象类型的属性,也可以用于声明PL/SQL变量。
2.1声明关联数组
关联数组的TYPE语句的语法如下:
TYPE table_type_name IS TABLE OF datatype [ NOT NULL] INDEX BY index_type;
其中:
table_type_name是你所创建的集合类型的名字,datatype是集合中唯一一列的数据类型,index_type是用来组织集合内容的索引的数据类型。而集合唯一以列的数据类型可以是下面这些:
- 标量数据类型:任何被PL/SQL支持的标量数据类型,比如VARCHAR2,CLOB,POSITIVE,DATE,或者BOOLEAN。
- 锚定数据类型:这种数据类型是从一个数据库表的列,之前已经定义的变量或者带有%TYPE属性的游标表达式推导出来的数据类型。我们也可以定义用%ROWTYPE声明或者根据一个用户定义的记录类型来定义一个记录的集合。
- 复杂的数据类型:从Oracle 9i数据库R2版本开始,你也可以把对象类型和集合类型作为集合的数据类型。
集合语法中的index_type定义索引下标的数据类型。在Oracle 9i数据库版本R2之前,只能是INDEX BY PLS_INTEGER。从Oracle 9i数据库版本R2开始,INDEX BY的数据类型可以是BINARY_INTEGER、及它的子类型、VARCHAR2(N)或者VARCHAR2列或变量的%TYPE锚定类型。
2.2声明嵌套表
可以数据库内或者PL/SQL代码块中声明嵌套表类型。
在数据库内创建一个嵌套表类型:
CREATE [OR REPLACE] TYPE type_name AS | IS TABLE OF element_datatype [ NOT NULL ];
删除数据库内的嵌套表类型:
DROP TYPE type_name [FORCE];
在PL/SQL中声明一个嵌套表类型:
TYPE type_name IS TABLE OF element_datatype [ NOT NULL ];
其中:
- OR REPLACE:允许我们重创建一个已经存在的类型。通过在语法中加上REPLACE的方式来重建类型,而不是先删除后再重新创建,可以把所有已经授予的权限都完整的保留下来。
- type_name:一个合法的SQL或者PL/SQL标志符。这也是我们以后在声明变量或者列时会用到的标识符。
- element_datatype:这是集合元素的数据类型。集合内所有元素都是一种类型的,可以是大部分标量数据类型、对象类型、或者REF对象类型。如果集合的元素是对象,对象类型本身不能再带有一个集合属性。如果你创建了一个其元素是RECORD类型的集合,记录的字段只能是标量或者是独享。明确的不可用于集合的数据类型包括BOOLEAN、NCHAR、NCLOB、NVARCHAR2、REF CURSOR、TABLE和VARRAY(非SQL数据类型)。
- NOT NULL:表明这种类型的变量不能有任何空元素。不过,集合本身可可以是原子级的空(未初始化)。
- FORCE:这个关键字告诉数据库的是,当要删除这个类型时,就算是其他类型中还有对这个类型的引用,也要强行删除这个类型。比如,如果在一个对象类型的定义中用到了某个特殊的集合类型,你可以使用FORCE关键字来强行删除这个集合类型。
2.3声明VARRAY
和嵌套表类型的声明一样,可以数据库内或者PL/SQL代码块中声明VARRAY类型。
在数据库内创建一个VARRAY类型:
CREATE [OR REPLACE] TYPE type_name AS | ISVARRAY(max_elements)OF element_datatype [ NOT NULL ];
删除数据库内的VARRAY类型:
DROP TYPE type_name [FORCE];
在PL/SQL中声明一个VARRAY类型:
TYPE type_name ISVARRAY(max_elements)OF element_datatype [ NOT NULL ];
其中:
- OR REPLACE:允许我们重创建一个已经存在的类型。通过在语法中加上REPLACE的方式来重建类型,而不是先删除后再重新创建,可以把所有已经授予的权限都完整的保留下来。
- type_name:一个合法的SQL或者PL/SQL标志符。这也是我们以后在声明变量或者列时会用到的标识符。
- element_datatype:这是集合元素的数据类型。集合内所有元素都是一种类型的,可以是大部分标量数据类型、对象类型、或者REF对象类型。如果集合的元素是对象,对象类型本身不能再带有一个集合属性。如果你创建了一个其元素是RECORD类型的集合,记录的字段只能是标量或者是独享。明确的不可用于集合的数据类型包括BOOLEAN、NCHAR、NCLOB、NVARCHAR2、REF CURSOR、TABLE和VARRAY(非SQL数据类型)。
- NOT NULL:表明这种类型的变量不能有任何空元素。不过,集合本身可可以是原子级的空(未初始化)。
- max_elements:VARRAY中元素的最大数量,这个值一旦声明就不能更改。
- FORCE:这个关键字告诉数据库的是,当要删除这个类型时,就算是其他类型中还有对这个类型的引用,也要强行删除这个类型。比如,如果在一个对象类型的定义中用到了某个特殊的集合类型,你可以使用FORCE关键字来强行删除这个集合类型。
3.集合变量的声明和初始化
3.1集合变量的声明
一旦我们创建好了集合类型,我们就可以根据这个集合类型声明该类型的变量。一个集合变量声明格式如下:
collection_name collection_type [:=collection_type(...)];
其中,collection_name是集合变量的名字,collection_type具有两层含义,它即代表着一个先前已经声明的集合类型的名字,同时也代表着(如果是嵌套表或者VARRAY的话)和该类型同名的构造函数。
构造函数的名字和类型的名字是相同的,并且接收一个用逗号分隔的元素列表作为参数。如果我们声明的是一个嵌套表或者VARRAY变量,我们在使用之前必须要先对这个变量进行初始化。
3.2集合变量的初始化
对于嵌套表类型集合变量和VARRAY类型集合变量,在使用集合变量之前必须要进行初始化,而对于关联数组类型不需要初始化。下面主要讨论嵌套表和VARRY的初始化。
3.2.1通过构造函数的显示初始化
通过构造函数显示地给集合变量初始。例如:
declare
vnt_employee nt_employee :=nt_employee(); --不带参数的构造函数初始化
vnt_employee nt_employee :=nt_employee('张三','李四','王五'); --带参数的构造函数初始化
begin
null;
end;
3.2.2直接赋值时的隐式初始化
如果两个集合实例是基于同一集合类型,我们可以把其中一个实例的全部内容拷贝给另一个,这就相当于进行了初始化。例如:
declare
vnt_employee nt_employee :=nt_employee('James','Lucy','Jordan');
vnt_foregin_employee nt_employee;
begin
vnt_foregin_employee := vnt_employee;
end;
3.2.3通过FETCH操作的隐式初始化
在使用FETCH或者 SELECT INTO语句从数据库提取提取一个集合并保存到一个集合变量时,集合变量会自动初始化,就像直接赋值一样。
declare
vnt_colors nt_color;
begin
select colors into vnt_colors from color_models; --表color_models的color列是嵌套表类型。
end;
3.2.4通过BULK COLLECT语句的隐式初始
使用BULK COLLECT INTO语句批量提取数据并保存到一个集合变量,集合变量会自动初始化,就像直接赋值一样。
declare
vnt_employee nt_employee; --未初始化
begin
selecte.ename bulk collect intovnt_employeefrom emp e;
end;
declare
cursor cur_employee is select e.ename from emp e;
vnt_employee nt_employee; --未初始化
begin
open cur_employee;
fetch cur_employee bulk collect into vnt_employee;
close cur_employee;
end;
4.集合方法
Oracle提供了提供许多内置的函数和过程可以用于获取集合的信息或者修改集合的内容,这些方法也叫做集合方法。下面给出这些方法的完整列表:
方法(函数或者过程)
|
说 明
|
COUNT函数
|
返回集合中现有元素的数量
|
DELETE过程
|
从集合中移除一个或者多个元素。如果不是重复移除,会减少COUNT的值,对于VARRAY,你只能删除集合的所有元素
|
EXISTS函数
|
根据某个指定的元素是否已经在集合中,返回TURE或者FALES
|
EXTEND过程
|
增加嵌套表或者VARRAY中元素的个数,同时增加COUNT的值
|
FIRST、LAST函数
|
返回可用的最小(FIRST)和最大(LAST)集合下标
|
LIMIT函数
|
返回VARRAY中允许ude最大元素数量
|
PRIOD、NEXT函数
|
返回紧挨着指定的下标之前(PRIOD)或者之后(NEXT)的下标值。你应该总是用PRIOD和NEXT在集合内遍历,尤其在使用稀疏(或者可能是稀疏)集合时更是如此
|
TRIM过程
|
从集合的尾部(定义的最大下标)移除集合元素
|
之所以把这些过程叫做方法,是因为使用这些集合内置程序的语法不同于调用过程和函数的正规语法。
5.集合类型对比
Oracle 集合类型对比
属性
|
关 联 数 组
|
嵌 套 表
|
可变长数组
|
维度
|
一维
|
一维
|
一维
|
是否可用于SQL
|
不可用
|
可用
|
可用
|
是否可作为表中列的数据类型
|
不可用
|
可以;数据是在“行外”保存的(一个独立的表)
|
可以;数据保存在“行内”(在同一个表中)
|
未初始化时的状态
|
空(不能是NULL);元素是为定义
|
自动就是NULL的;对元素的引用是非法的
|
自动就是NULL;对元素的引用是非法的
|
初始化
|
在声明时自动完成
|
通过构造函数,或者赋值,或者fetch操作完成
|
通过构造函数,或者赋值,或者fetch操作完成
|
在PL/SQL中元素的引用方式
|
BINARY_INTEGER以及其子类型
|
VARCHAR2(Oracle 9i数据库R2版本或者更高版本)
|
1到2 147 483 647间的整数
|
是否稀疏
|
是
|
开始不是;经过删除后就成稀疏了
|
不是
|
是否有界
|
无界
|
可以扩展
|
有界
|
可以随时对任意一个元素赋值
|
可以
|
不可以,可以需要用EXTEND进行扩展
|
不可以;可以用EXTEND进行扩展,而且扩展时不能超出上边界
|
扩展的方法
|
给一个新下标指向的元素赋值
|
使用内置的EXTEND过程(或者TRIM进行压缩),没有预定义的最大值
|
使用内置EXTEND过程(或者TRIM进行压缩),但是最大只能到声明的最大尺寸
|
可以比较相等与否
|
不可以
|
可以,要求是Oracle 10g或者以后的版本
|
不可以
|
是否可以通过集合操作符进行操作
|
不可以
|
可以,要求是Oracle 10g或者以后的版本
|
不可以
|
存取数据时是否会保留顺序或者下标
|
N/A
|
不保留
|
保留
|
6.集合示例
6.1关联数组示例
declare
type nt_foregn_employee is table of varchar2(30) index by binary_integer;
vnt_foregn_employees nt_foregn_employee;
v_row number;
begin
vnt_foregn_employees(-230002) := 'SCOTT';
vnt_foregn_employees(-23) := 'JONES';
vnt_foregn_employees(1) := 'ALLEN';
vnt_foregn_employees(5934) := 'CLARK';
vnt_foregn_employees(13342) := 'ADAMS';
vnt_foregn_employees(8234223) := 'KING';
--使用FIRST方法获取集合中的一个行号
v_row := vnt_foregn_employees.first;
while (v_row is not null) loop
dbms_output.put_line(vnt_foregn_employees(v_row));
v_row := vnt_foregn_employees.next(v_row);
end loop;
end;
在稀疏集合中,经常需要使用NEXT方法遍历集合,提取数据。
6.2嵌套表示例
declare
type nt_employee is table of emp%rowtype;
vnt_employees nt_employee := nt_employee(); --构造函数显示初始化
c_big_number number := power(2, 31);
l_start_time pls_integer;
cursor cur_employee is
select * from emp;
vrt_employees cur_employee%rowtype;
begin
open cur_employee;
loop
fetch cur_employee
into vrt_employees;
exit when cur_employee%notfound;
vnt_employees.extend;
vnt_employees(vnt_employees.last) := vrt_employees;
end loop;
close cur_employee;
dbms_output.put_line(vnt_employees.count);
end;
6.3VARRAY实例
create or replace type nt_course is varray(5) of varchar2(100);
create table students( student_name varchar2(20) , cource nt_course);
declare
vnt_nt_courses nt_course := nt_course();
begin
vnt_nt_courses.extend(2);
vnt_nt_courses(1) := 'English';
vnt_nt_courses(2) := 'Chinese';
insert into students
(student_name, cource)
values
('chiclewu', vnt_nt_courses);
end;
可以使用TABLE函数把一个集合映射成数据库表.例如,要获取student表中课程列的记录。
select * from table (select s.cource from students s);
参考:
Oracle PL/SQL程序设计(第五版) Steven Feuersterin & Bill Pribyl著 张晓明译
分享到:
相关推荐
### Oracle集合类型输出参数的PL/SQL存储过程及其Java调用 #### 1. 引言 存储过程因其高效执行、事务处理能力以及安全性,在数据库应用程序中被广泛应用。特别是使用Oracle数据库时,PL/SQL(一种专为Oracle设计的...
Oracle集合类型输出参数的PL/SQL存储过程及Java调用主要涉及如何在Oracle数据库中使用存储过程处理集合数据,并在Java应用中调用这些过程。本文档介绍了一种使用索引表作为输出参数的方法,以及如何在Java中处理返回...
Oracle数据库系统提供了多种数据类型,其中包括了三种主要的集合数据类型:VARRAY(变量数组)、NESTED TABLE(嵌套表)和 Associative Array(关联数组,也称为INDEX BY TABLE)。这三种集合数据类型在存储和操作一...
在深入了解Oracle PL/SQL中的集合之前,先回顾一下与集合相关的概念和术语,包括不同集合类型的描述及其示例。 ##### 12.1.1 集合概念和术语 **元素和索引值** - **元素**:集合是由一系列数据项或元素组成的数据...
### Oracle SQL 集合知识点详解 #### 一、Oracle 安装完成后的初始口令 在Oracle数据库安装完成后,存在一系列预设的账号及其初始密码。这些账号对于数据库的安全性和管理至关重要。以下是一些常见账号及其初始口令...
6. **oci8_collection.c**:提供了对Oracle集合类型的支持,允许在PHP中操作Oracle的数组类型数据。 7. **CREDITS**:列出oci8扩展开发和贡献者的名单,体现了开源社区的协作精神。 8. **oci8.dsp**:可能是Visual...
..Oracle11集合类型输出参数的PLSQL存储过程及其Java调用.docx
..Oracle11集合类型输出参数的PLSQL存储过程及其Java调用.pdf
7. **集合型**:VARRAY和NESTED TABLE是两种集合类型,用于存储数组或表格形式的数据。 二、Oracle 10g数据库管理员(DBA)操作 1. **数据库创建与管理**:DBCA(Database Configuration Assistant)用于图形化...
在Oracle数据库管理中,经常会遇到各种错误,本文主要讨论了三个...正确识别错误类型并采取相应的解决措施是关键。在日常运维中,定期备份、监控日志以及熟悉常见错误处理方法能够有效地减少故障发生并快速恢复服务。
Oracle复合类型之RECORD的深入浅出 Oracle复合类型之RECORD是Oracle数据库中的一种复杂数据类型,它允许用户定义一个包含多个字段的记录类型,类似于结构体或对象。 RECORD类型可以用于存储和处理复杂数据,使得...
Oracle 数据类型是指一组性质相同的值的集合以及定义于这个值集合上的一组操作的总称。在 Oracle 数据库中,数据类型可以分为字符型、数值型、日期型和其它类型等几类。 Oracle 数据类型的使用和研究是早于计算机...
在Java中调用Oracle函数并处理返回的Oracle特定数据类型,如集合或索引表,通常涉及到Oracle的PL/SQL包和Java的JDBC驱动。以下是对这个主题的详细说明: 1. **Oracle索引表类型**: Oracle索引表是一种PL/SQL数据...
数据类型是由一组具有相同特性的值及其上定义的操作组成的一个集合。在现实世界中,为了有效地保存和处理不同类型的信息,我们需要使用不同的数据类型。例如,整型数据用于表示整数值,支持常见的数学运算如加、减、...
Oracle提供了两种主要的集合类型:VARRAY(固定大小数组)和NESTED TABLE(可变大小表格)。VARRAY有固定的元素数量限制,而NESTED TABLE则可以动态增长。 例如,你可以创建一个存储PersonType对象的VARRAY类型: ...
在"ORCL数据库相关文档.rar"这个压缩包中,我们可以找到一系列关于Oracle数据库的重要资料,尤其是"Oracle命令集合"部分,它涵盖了Oracle数据库管理和操作的各种常见命令。 首先,创建实例是Oracle数据库管理的基础...
ADO.NET提供了基础的数据访问接口,而ODP.NET是Oracle官方提供的专用.NET数据提供者,它具有更优秀的性能和对Oracle特性的支持,例如高级的游标处理、LOB数据类型处理等。 OracleHelper 还可能包含对ORM(Object-...
Oracle数据库在处理错误和异常时有一套完整的机制,这些异常主要分为预定义异常和自定义异常。预定义异常是Oracle系统已经内置的一些常见错误,它们都有对应的错误代码(ORA-xxx)。下面,我们将深入探讨一些常见的...
Oracle提供了许多其他功能,如数学函数、转换函数、日期和时间函数、集合函数、聚合函数等,使得数据库操作和查询变得极其灵活和强大。理解并熟练使用这些函数和数据类型是Oracle数据库管理的基础。
在PL/SQL中,Oracle提供了三种集合类型,它们分别是联合数组(Associative Array)、内嵌表(Nested Table)和索引表(Index-By Table),这些类型为处理和操作一维数据提供了强大的工具。让我们逐一深入理解这三种...