`

PL/SQL高级应用 - 集合

阅读更多
PL/SQL高级应用 - 集合

读者可能会问,为什么要使用集合?毕竟,使用带有外键的两个表已经允许创建数据之间的关联。答案是:相对于使用两个表,存储在集合中的数据可以被数据库更快地访问。通常情况下,如果数据只被一个表使用,那么使用集合。PL/SQL提供了3种不同的集合类型:index-by表(PL/SQL 2.0及更高版本)、嵌套表(PL/SQL 8.0及更高版本)和可变数组(PL/SQL 8.0及更高版本)。如下所示的程序例子介绍了上述3种集合类型的使用方法。


index-by表

index-by表类似于C语言中的数组,声明index-by表的方法如下:

TYPE tabletype IS TABLE OF type INDEX BY BINARU_INTEGER;


其中,tabletype是指所定义的新类型的类型名;type是要定义的index-by表的类型。

下例是一个定义index-by表的代码实例:

TYPE Country_Name IS TABLE OF COUNTRIES.COUNTRIES_NAME%TYPE

         INDEX BY BINARY_INTEGER;  --声明类型

v_Name Country_Name;              --声明变量


声明了类型和变量后,就可以用以下语句使用index-by表中的单个元素:

v_Name(index)

其中,index是指表中的第几个元素。



index的数据类型是BINARY_INTEGER。

1.元素赋值

我们可以使用以下语句给表中的元素赋值:

BEGIN

v_Name(1):= ‘China’;

v_Name(2):= ‘USA’;

END;



index-by表中的元素不是按特定顺序排列的,这是与C语言数组不同的,在C语言中数组在内存中是顺序存储的,因此元素的下标也是有序的。

也就是说下面的元素赋值也是合法的:

BEGIN

v_Name(1):= ‘China’;

v_Name(-2):= ‘USA’;

v_Name(5):= ‘Italy’;

END;



index-by表的元素的个数只是受到BINARY_INTEGER类型的限制,即index的范围为–2 147 483 647~2 147 483 647。因此只要在此范围内给元素赋值都是合法的。

2.调用不存在的元素

需要注意的是,对所有的index-by表的元素的调用之前都必须首先给该元素赋值,要不然系统就会提示出错。
DECLARE

TYPE StudyTab IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER;

v_StudyTab StudyTab;

BEGIN

FOR v_Count IN 1..5 LOOP

  v_StudyTab(v_Count):=v_Count*100;

END LOOP;

FOR v_Count IN 1..5 LOOP

  DBMS_OUTPUT.PUT_LINE(v_StudyTab(v_Count));

END LOOP;

END;


在上面的代码中首先给各个元素赋值,然后将其输出,结果如下:

100

200

300

400

500

PL/SQL 过程已成功完成。

当将第二个FOR循环中的循环范围设置为1..6时,由于v_StudyTab(6)元素没有赋值,因此系统会出现如下的错误信息:

100

200

300

400

500

DECLARE

*

ERROR 位于第 1 行:

ORA-01403: 未找到数据

ORA-06512: 在line 10
嵌套表

嵌套表的声明和index-by表的声明十分类似,具体声明如下:

TYPE table_name is TABLE OF table_type [NOT NULL];




嵌套表与index-by表的唯一不同就是没有了INDEX BY BINARU_INTEGER子句,因此区别这两种类型的唯一方法就是看是否含有INDEX BY BINARU_INTEGER子句。

1.嵌套表初始化

嵌套表的初始化与index-by表的初始化是完全不同的。在声明了类型以后,再声明一个index-by表变量类型,如果没有给该表赋值,那么该表就是一个空的index-by表,但是在以后的语句中可以继续向index-by表中添加元素;而声明了嵌套表变量类型是指如果嵌套表中没有任何元素,那么它会自动初始化为NULL,并且是只读的,如果还想向这个嵌套表中添加元素,系统就会提示出错。下面的代码很好地说明了嵌套表的初始化:

DECLARE

TYPE StudyTab IS TABLE OF VARCHAR2(20);

v_StudyTab StudyTab:=StudyTab('Tom','Jack','Rose');

BEGIN

FOR v_Count IN 1..3 LOOP

  DBMS_OUTPUT.PUT_LINE(v_StudyTab(v_Count));

END LOOP;

END;

以上是嵌套表正确初始化的过程,系统会输出如下信息:

Tom

Jack

Rose

PL/SQL 过程已成功完成。

嵌套表初始化时没有元素,而后如果向其中添加元素,系统就会提示出错:

DECLARE

TYPE StudyTab IS TABLE OF VARCHAR2(20);

v_StudyTab StudyTab;

BEGIN

v_StudyTab(4):='Ronaldo';

END;

DECLARE

*

ERROR 位于第 1 行:

ORA-06531: 引用未初始化的收集

ORA-06512: 在line 5

如果嵌套表初始化了,但是还向其中添加元素,则出错信息如下:

DECLARE

*

ERROR 位于第 1 行:

ORA-06533: 下标超出数量

ORA-06512: 在line 5

2.元素序列

嵌套表与index-by表十分相似,只是嵌套表在结构上是有序的,而index-by表是无序的,也就是说,如果给一个嵌套表赋值,那么嵌套表元素的index将会从1开始依次递增,请看如下的代码:

D
ECLARE

TYPE NumTab IS TABLE OF NUMBER(4);

v_Num NumTab:=NumTab(1,3,4,5,7,9,11);

BEGIN

FOR v_Count IN 1..7 LOOP

  DBMS_OUTPUT.PUT_LINE( 'v_Num(' || v_Count || ')=' || v_Num(v_Count));

END LOOP;

END;

系统执行结果如下:

v_Num(1)=1

v_Num(2)=3

v_Num(3)=4

v_Num(4)=5

v_Num(5)=7

v_Num(6)=9

v_Num(7)=11

在此可以清楚地看到嵌套表是有序的。
可变数组

可变数组的声明如下:

TYPE type_name IS {VARRAY|VARYING ARRAY}(maximum_size)

         OF element_type[NOT NULL];

         --type_name是可变数组的类型名。

         --maximum_size是指可变数组元素个数的最大值。

         --element_type是指数组元素的类型。


可变数组的可变是指当定义了数组的最大上限后,数组元素的个数可以在这个最大上限内变化,但是不得超过最大上限,当数组元素的个数超过了最大上限后,系统就会提示出错。可变数组的存储和C语言的数组是相同的,各个元素在内存中是连续存储的。

下面是一个合法的可变数组的声明:

DECLARE

         --定义一个包含星期的可变数组

TYPE Dates IS VARRAY(7) OF VARCHAR2(10);

         --定义一个包含月份的可变数组

TYPE Months IS VARRAY(12) OF VARCHAR2(10);


与嵌套表一样,可变数组也需要初始化,初始化时需要注意的是赋值的数量必须保证不大于可变数组的最大上限。下例是可变数组初始化的实例:
DECLARE

         TYPE Dates IS VARRAY(7) OF VARCHAR2(10);

v_Dates Dates:=Dates('Monday','Tuesday','Wesdnesday');

BEGIN

DBMS_OUTPUT.PUT_LINE(v_Dates(1));

DBMS_OUTPUT.PUT_LINE(v_Dates(2));

DBMS_OUTPUT.PUT_LINE(v_Dates(3));

END;


与嵌套数组一样,当元素个数超出了最大上限后,系统会提示出错,这里不再重复介绍,读者可以将上例改造一下,如将最后一个输出语句的值改为v_Dates(4)。
集合的属性和方法

index-by表、嵌套表和可变数组都是对象类型,因此它们本身就有属性或者方法,集合的属性和方法的调用与其他对象类型的调用相同:

Object.Attribute或者Object.Method

下面将来介绍集合类型中几种常用的属性和方法。

(1)COUNT:COUNT是一个整数,它用来返回集合中的数组元素个数,下例说明了该属性的用法。

DECLARE

  --定义3种集合类型

TYPE Name IS TABLE OF VARCHAR(20) INDEX BY BINARY_INTEGER;

  TYPE Pwd IS TABLE OF VARCHAR(20);

  TYPE Dates IS VARRAY(7) OF VARCHAR2(10);

  --声明集合并初始化后两种集合类型

v_Name Name;

  v_Pwd Pwd:=Pwd('10000','12345','22','yes','no');

  v_Dates Dates:=Dates('Monday','Sunday');

BEGIN

  --初始化Index-By表

v_Name(1):='Tom';

  v_Name(-1):='Jack';

  v_Name(4):='Rose';

  --输出3种集合类型的元素个数

DBMS_OUTPUT.PUT_LINE('The Index-By Count is : '||v_Name.Count);

  DBMS_OUTPUT.PUT_LINE('The Nested Count is : '||v_Pwd.Count);

  DBMS_OUTPUT.PUT_LINE('The Varray Count is : '||v_Dates.Count);

END;

系统运行结果如下:

The Index-By Count is : 3

The Nested Count is : 5

The Varray Count is : 2

PL/SQL 过程已成功完成。

COUNT属性在PL/SQL编程中是十分有用的属性,对于那些集合元素的个数未知,而又想对其进行操作的模块是十分方便的。

(2)DELETE:DELETE是用来删除集合中的一个或者多个元素。需要注意的是由于DELETE方法执行的删除操作是大小固定的,所以对于可变数组来说是没有DELETE方法的(如果对可变数组执行DELETE方法,将会出错)。DELETE有以下3种方式:

l          DELETE:没带参数的DELETE方法即将整个集合删除。

l          DELETE(x):即将位于集合表中第x个位置的元素删除。

l          DELETE(x,y):即将集合表中从第x个元素到第y个元素之间的所有元素删除。



执行DELETE方法后,集合的COUNT值将会立刻变化;而且当要删除的元素不存在时,DELETE不会报错,而是跳过该元素,继续执行下一步操作。

下面是一个DELETE方法和COUNT属性联合使用的例子:

DECLARE

  TYPE Pwd IS TABLE OF VARCHAR(20);

  v_Pwd Pwd:=Pwd('10000','12345','22','yes','no','OK','All','Hello','Right','Left','FootBall');

BEGIN

--输出表的原始数据元素的个数

DBMS_OUTPUT.PUT_LINE('The original table count is : ');

DBMS_OUTPUT.PUT_LINE(v_Pwd.count);

--删除一个元素后再输出表的元素的个数

v_Pwd.DELETE(4);

DBMS_OUTPUT.PUT_LINE('After delete a element, table count is : ');

DBMS_OUTPUT.PUT_LINE(v_Pwd.count);

--删除一些元素后输出表的元素的个数

v_Pwd.DELETE(6,8);

DBMS_OUTPUT.PUT_LINE('After delete some element, table count is : ');

DBMS_OUTPUT.PUT_LINE(v_Pwd.count);

END;

(3)EXISTS:EXISTS用来判断集合中的元素是否存在。具体用法如下。

EXISTS(x),即判断位于位置x处的元素是否存在,如果存在则返回TRUE,如果x大于集合的最大范围,则返回FALSE。



使用EXISTS判断时,只要在指定位置处有元素存在即可,即使该处的元素为 NULL,EXISTS也会返回TRUE。

(4)EXTEND:EXTEND用来将元素添加到集合的末端,具体形式有以下几种。

l          EXTEND:没带参数的EXTEND是将一个NULL元素添加到集合的末端。

l          EXTEND(x):该形式是将x个NULL元素添加到集合的末端。

l          EXTEND(x,y):该形式是将x个位于y的元素添加到集合的末端。

请看如下的代码:

DECLARE

  TYPE Pwd IS TABLE OF VARCHAR(20);

  v_Pwd Pwd:=Pwd('10000','12345','22','yes','no','OK','All','Hello','Right','Left','FootBall');

  v_Count INTEGER;

BEGIN

--输出初始集合的最后一个元素

v_Count:=v_Pwd.LAST;

DBMS_OUTPUT.PUT_LINE(v_Pwd(v_Count));

--向集合添加了两个'12345'(位于第2的元素)后,输出集合的最后一个元素

v_Pwd.EXTEND(2,'2');

v_Count:=v_Pwd.LAST;

DBMS_OUTPUT.PUT_LINE(v_Pwd(v_Count));

--在集合末端添加两个NULL值后,将最后一个位置赋值,并输出

v_Pwd.EXTEND(2);

v_Count:=v_Pwd.LAST;

v_Pwd(15):='Basketball';

DBMS_OUTPUT.PUT_LINE(v_Pwd(v_Count));

END;

系统运行结果如下:

FootBall

12345

Basketball

PL/SQL 过程已成功完成。



由于Index-by表元素的随意性,因此EXTEND方法只对嵌套表和可变数组有效。

(5)FIRST和LAST:FIRST用来返回集合第一个元素的位置,而LAST则是返回集合最后一个元素的位置。

(6)LIMIT:LIMIT用来返回集合中的最大元素个数。由于嵌套表没有上限,所以当嵌套表使用 LIMIT时,总是返回NULL值。如下例:

DECLARE

  TYPE Pwd IS TABLE OF VARCHAR(20);

  v_Pwd Pwd:=Pwd('10000','12345','22','yes','no','OK','All','Hello','Right','Left','FootBall');

  TYPE Name IS VARRAY(20) OF VARCHAR(20);

  v_Name Name:=Name('10000','12345','22','yes','no','OK','All','Hello','Right','Left','FootBall');

BEGIN

--分别输出嵌套表和可变数组的LIMIT值

DBMS_OUTPUT.PUT_LINE('The NestedTable Limit is : '||v_Pwd.LIMIT);

DBMS_OUTPUT.PUT_LINE('The VarrayTable Limit is : '||v_Name.LIMIT);

END;

系统运行结果如下:

The NestedTable Limit is :

The VarrayTable Limit is : 20

PL/SQL 过程已成功完成。

(7)NEXT和PRIOR:NEXT和PRIOR在使用时后面都会接一个参数,形式如下:

NEXT(x)、PRIOR(x)

其中,NEXT(x)返回的是位置为x处的元素后面的那个元素,而PRIOR(x) 则刚好相反,它返回的是x处的元素前面的那个元素。

通常NEXT和PRIOR一起使用,FIRST和LAST一起使用,用来进行循环处理:

DECLARE

  TYPE Pwd IS TABLE OF VARCHAR(20);

  v_Pwd Pwd:=Pwd('10000','12345','22','yes','no','OK','All','Hello','Right','Left','FootBall');

  v_Count INTEGER;

BEGIN

v_Count:=v_Pwd.FIRST;

WHILE v_Count<=v_Pwd.LAST LOOP

  DBMS_OUTPUT.PUT_LINE(v_Pwd(v_Count));

  v_Count:=v_Pwd.NEXT(v_Count);

END LOOP;

END;

系统执行结果如下:

10000

12345

22

yes

no

OK

All

Hello

Right

Left

FootBall

PL/SQL 过程已成功完成。

上例中是顺序打印集合中的元素,其实通过灵活运用这4个函数我们还可以反向打印集合中的各个元素,具体代码如下:

DECLARE

  TYPE Pwd IS TABLE OF VARCHAR(20);

  v_Pwd Pwd:=Pwd('10000','12345','22','yes','no','OK','All','Hello','Right','Left','FootBall');

  v_Count INTEGER;

BEGIN

v_Count:=v_Pwd.LAST;

WHILE v_Count>=v_Pwd.FIRST LOOP

  DBMS_OUTPUT.PUT_LINE(v_Pwd(v_Count));

  v_Count:=v_Pwd.PRIOR(v_Count);

END LOOP;

END;

(8)TRIM:TRIM方法用来删除集合末端的元素。

其具体形式如下。

l          TRIM:没有参数的TRIM是从集合中末端删除一个元素。

l          TRIM(x):该形式是从集合末端删除x个元素,其中x要小于集合的COUNT数,否则系统会提示出错。



与EXTEND一样的是,由于Index-by表元素的随意性,因此TRIM方法只对嵌套表和可变数组有效。
分享到:
评论

相关推荐

    Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发

    《Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发》是一本深入探讨Oracle数据库中的PL/SQL编程的专业书籍。PL/SQL是Oracle数据库特有的编程语言,它结合了SQL的查询能力与过程式编程语言的功能,使得数据库...

    Oracle PL SQL专家指南_高级PLSQL解决方案的设计与开发

    - 游标表达式和游标变量的高级应用 - PL/SQL包和类型:创建和使用 - PL/SQL中的对象关系编程 10. **AppendixA - 实战案例与解决方案** - 解决实际问题的PL/SQL代码示例 - 复杂业务逻辑的实现 - 应对挑战性的...

    Oracle PL/SQL程序设计(第5版)(上下册)

    - **集合与记录**:学习如何使用PL/SQL中的集合和记录类型,这些结构可以帮助更高效地处理数据集。 - **游标**:介绍游标的使用方法,包括隐式游标和显式游标,以及如何利用游标遍历查询结果。 #### 四、PL/SQL中的...

    pl/sql 学习资料

    PL/SQL是Oracle数据库系统中的一个关键组成部分,它是一种结合了SQL语言与过程式编程的高级语言,主要用于数据库管理和应用程序开发。在这个“PL/SQL学习资料”压缩包中,包含了十一个PDF文件,覆盖了从基础到进阶的...

    ORACLE PL/SQL从入门到精通

    ORACLE PL/SQL是从入门到精通的专业知识,涵盖了数据库开发与管理的多个方面,包括...这本书籍将为读者提供一个全面、系统的学习路径,帮助数据库管理员、开发人员深入理解并掌握ORACLE PL/SQL的强大功能和应用技巧。

    PL/SQL开发,性能优化等文档

    2. PL/SQL高级特性 - 包(Package):将相关的过程和函数封装在一起,提高代码复用性。 - 游标:用于处理单行或多行查询结果,是PL/SQL中重要的数据处理工具。 - 表类型和记录类型:允许在PL/SQL中存储和操作集合...

    Oracle Database 12c PL/SQL开发指南 实例源代码

    PL/SQL是Oracle专为数据库管理设计的一种过程化编程语言,它结合了SQL查询语言的威力与高级编程语言的灵活性,使得数据库开发者能够创建复杂的应用程序逻辑。 在"Oracle Database 12c PL/SQL开发指南(第7版)"这...

    PL/SQL入门到精通书的源代码

    本资料“PL/SQL入门到精通书的源代码”是一份针对初学者到高级用户的实践教程,旨在帮助读者深入理解和掌握PL/SQL的各个方面。 在学习PL/SQL时,你需要了解以下几个关键知识点: 1. **基础语法**:PL/SQL由声明...

    Oracle PL/SQL程序设计(第5版)(下册)第二部分

    《Oracle PL/SQL程序设计(第5版)》基于Oracle数据库11g,从PL/SQL编程、PL/SQL程序结构、PL/SQL程序数据、PL/SQL中的SQL、PL/SQL应用构建、高级PL/SQL主题这6个方面详细系统地讨论了PL/SQL以及如何有效地使用它。...

    精通Oracle 10g SQL和PL/SQL

     本书是专门为oracle开发人员而提供的编程指南 通过学习本书 读者不仅可以掌握编写sql语句和pl/sql块的基础知识 而且还可以掌握sql高级特征 正则表达式 flashback查询 merge语句 sql:1999连接 和pl/sql高级特征 ...

    PL/SQL编程(电子版)

    【PL/SQL编程】是Oracle数据库中用于数据库管理和应用程序开发的一种高级过程语言,它结合了SQL查询语言的威力和高级编程语言的灵活性。本章详细介绍了PL/SQL的基础知识,帮助初学者快速掌握该语言。 **4.1 PL/SQL...

    Oracle PL/SQL 高级程序设计

    ### Oracle PL/SQL 高级程序设计 #### 第1章:PL/SQL介绍 ##### 1.1 为什么引入PL/SQL语言 Oracle数据库作为一款关系型数据库管理系统,支持多种编程语言来访问和管理其中的数据。其中最常用的是SQL语言,它是一...

    oracle 中 pl/sql 只是学习方法

    3. **集合和游标**:集合是PL/SQL中处理多行数据的有效工具,如VARRAYs(固定大小数组)和associative arrays(关联数组)。游标则允许我们一行一行地处理查询结果,是处理动态数据的重要手段。 4. **存储过程和...

    Oracle8i PL SQL 高级程序设计.zip 高清下载

    Oracle8i PL/SQL高级程序设计是一门深入探讨Oracle数据库管理系统中PL/SQL编程语言的学科。Oracle数据库是全球广泛使用的数据库系统之一,而PL/SQL则是其内建的、专为数据库操作设计的结构化查询语言。这个压缩包...

    Oracle8 PL/SQL高级程序设计.rar

    "Oracle8 PL/SQL高级程序设计"的主题涵盖了在Oracle8环境中使用PL/SQL进行复杂编程和数据库管理的核心概念和技术。 PL/SQL(Procedural Language/Structured Query Language)是SQL的扩展,它将SQL的查询能力与过程...

    Pl/SQL programming 超全经典官方多本书籍资料

    书中不仅讲解了基本概念,还包括了许多高级主题,如并发控制、事务管理、错误处理策略、性能调优技巧,以及PL/SQL在分布式环境下的应用。第五版更新了最新的Oracle版本特性,提供了丰富的示例和实战经验,帮助开发者...

    oracle数据库 PL/SQL教程

    PL/SQL高级特性 - **动态SQL**:允许在运行时构建和执行SQL语句。 - **集合**:用于存储多个同类型的数据元素,如VARRAY和NATIVE_ARRAY。 - **记录**:可以存储一组不同类型的值,类似于其他语言中的结构体或类。 ...

    Oracle PL SQL程序设计 上 第五版(代码示例)

    《oracle pl/sql程序设计(第5版)》基于oracle数据库11g,从pl/sql编程、pl/sql程序结构、pl/sql程序数据、pl/sql中的sql、pl/sql应用构建、高级pl/sql主题6个方面详细系统地讨论了pl/sql以及如何有效地使用它。...

    PL/SQL 核心基础代码

    本资源"PL/SQL 核心基础代码"是针对PL/SQL初学者的一个宝贵资料集合,包含了一系列核心基础部分的代码实例,旨在帮助学习者更好地理解和掌握PL/SQL编程。 在PL/SQL中,主要涉及以下几个关键知识点: 1. **声明变量...

Global site tag (gtag.js) - Google Analytics