PL/SQL — 集合及常用方法
PL/SQL中提供了常用的三种集合联合数组、嵌套表、变长数组,而对于这几个集合类型中元素的操作,PL/SQL提供了相应的函数或过程来操纵数组中的元素或下标。这些函数或过程称为集合方法。一个集合方法就是一个内置于集合中并且能够操作集合的函数或过程,可以通过点标志来调用。本文主要描述如何操作这些方法。
一、集合类型提供的方法与调用方式
1、集合的方法与调用方式
EXISTS
函数EXISTS(n)在第n个元素存在的情况下会返回TRUE,否则返回FALSE。
通常使用EXISTS和DELETE来维护嵌套表。其中EXISTS还可以防止引用不存在的元素,避免发生异常。当下标越界时,EXISTS会返回FALSE,而不是抛出SUBSCRIPT_OUTSIDE_LIMIT异常。
COUNT
COUNT能够返回集合所包含的元素个数,对于大小不确定的情形则COUNT非常有用。
可以在任何可以使用整数表达式的地方使用COUNT函数,如作为for循环的上限。计算元素个数时,被删除的元素不会被count所统计。对于变长数组来说,COUNT值与LAST值恒等。对于嵌套表来说,正常情况下COUNT值会和LAST值相等。但是,当我们从嵌套表中间删除一个元素,COUNT值就会比LAST值小。
LIMIT
用于检测集合的最大容量。
由于嵌套表和关联数组都没有上界限制,所以LIMIT总会返回NULL。对于变长数组,LIMIT会返回它所能容纳元素的个数最大值,该值是在变长数组声明时指定的,并可用TRIM和EXTEND方法调整。
FIRST,LAST
FIRST和LAST会返回集合中第一个和最后一个元素在集合中的下标索引值。
对于使用VARCHAR2类型作为键的关联数组来说,会分别返回最低和最高的键值;键值的高低顺序是基于字符串中字符的二进制值。但是,如果初始化参数NLS_COMP被设置成ANSI的话,键值的高低顺序就受初始化参数NLS_SORT所影响了。
空集合的FIRST和LAST方法总是返回NULL。只有一个元素的集合,FIRST和LAST会返回相同的索引值。
对于变长数组,FIRST恒等于1,LAST恒等于COUNT。
对于嵌套表,FIRST通常返回1,如果删除第一个元素,则FIRST的值大于1,如果删除中间的一个元素,此时LAST就会比COUNT大。
在遍历元素时,FIRST和LAST都会忽略被删除的元素。
PRIOR,NEXT
PRIOR(n)会返回集合中索引为n的元素的前驱索引值;NEXT(n)会返回集合中索引为n的元素的后继索引值。如果n没有前驱或后继,PRIOR(n)或NEXT(n)就会返回NULL。
对于使用VARCHAR2作为键的关联数组来说,它们会分别返回最低和最高的键值;键值的高低顺序是基于字符串中字符的二进制值。
PRIOR和NEXT不会从集合的一端到达集合的另一端,即最末尾元素的的next不会指向集合中的first。
在遍历元素时,PRIOR和NEXT都会忽略被删除的元素,即如果prior(3)之前的2被删除则指向1,如果1也被删除则返回null。
EXTEND
用于扩大嵌套表或变长数组的容量,该方法不能用于联合数组。
EXTEND有三种形式
EXTEND 在集合末端添加一个空元素
EXTEND(n) 在集合末端添加n个空元素
EXTEND(n,i) 把第i个元素拷贝n份,并添加到集合的末端
对嵌套表或变长数组添加了NOT NULL约束之后,不能使用EXTEND的前两种形式。
EXTEND操作的是集合内部大小,其中也包括被删除的元素。所以,在计算元素个数的时候,EXTEND也会把被删除的元素考虑在内。
对于使用DELETE方法操作的元素,PL/SQL会保留其占位符,后续可以重新利用。
TRIM
从集合的末尾删除一个(TRIM)或指定数量TRIM(n)的元素,PL/SQL对TRIM掉的元素不再保留占位符。如果n值过大的话,TRIM(n)就会抛出SUBSCRIPT_BEYOND_COUNT异常。
通常,不要同时使用TRIM和DELETE方法。可把嵌套表当作定长数组,只使用DELETE方法,或是当作栈,只对它使用TRIM和EXTEND方法。
DELETE
删除集合中的所有或指定范围的元素。
DELETE 删除集合中所有元素 。
DELETE(n) 从以数字作主键的关联数组或者嵌套表中删除第n个元素。如果关联数组有一个字符串键,对应该键值的元素就会被删除。如果n为空,DELETE(n)不会做任何事情。
DELETE(m,n) 从关联数组或嵌套表中,把索引范围m到n的所有元素删除。如果m值大于n或是m和n中有一个为空,那么DELETE(m,n)就不做任何事。
PL/SQL会为使用DELETE方式删除的元素保留一个占位符,后续可以重新为被删除的元素赋值。
注,不能使用delete方式删除变长数组中的元素。
调用方式:
collection_name.method_name[(parameters)]
2、集合方法注意事项
1)集合的方法不能在SQL语句中使用。
2)EXTEND和TRIM方法不能用于关联数组。
3)EXISTS,COUNT,LIMIT,FIRST,LAST,PRIOR和NEXT是函数;EXTEND,TRIM和DELETE是过程。
4)EXISTS,PRIOR,NEXT,TRIM,EXTEND和DELETE对应的参数是集合的下标索引,通常是整数,但对于关联数组来说也可能是字符串。
5)只有EXISTS能用于空集合,如果在空集合上调用其它方法,PL/SQL就会抛出异常COLLECTION_IS_NULL。
二、各个方法综合演示
-->示例1
DECLARE
output VARCHAR2( 300 );
TYPE index_by_type IS TABLE OF VARCHAR2( 10 ) INDEX BY BINARY_INTEGER;
index_by_table index_by_type;
TYPE nested_type IS TABLE OF NUMBER;
//在声明块对嵌套表进行初始化并赋值
nested_table nested_type := nested_type( 10,20,30,40 ,50 ,60 ,70,80 ,90,100 );
BEGIN
FOR i IN 1 .. 10
LOOP
index_by_table( i ) := 'Value_' || i;
END LOOP;
DBMS_OUTPUT.put_line( '------------- Before deleted ----------------' );
//使用了first,last,作循环计数器上下标输出当前联合数组的所有元素
FOR i IN index_by_table.FIRST .. index_by_table.LAST
LOOP
output := output || NVL( TO_CHAR( index_by_table( i ) ), 'NULL' ) || ' ';
END LOOP;
DBMS_OUTPUT.put_line( 'Element of Index_by_table are: ' || output );
output := '';
//使用了count,作循环计数器上下标输出当前嵌套表的所有元素
FOR i IN 1 .. nested_table.COUNT
LOOP
output := output || NVL( TO_CHAR( nested_table( i ) ), 'NULL' ) || ' ';
END LOOP;
DBMS_OUTPUT.put_line( 'Element of nested_table are: ' || output );
//EXISTS函数判断联合数组中的第3个元素是否存在
IF index_by_table.EXISTS( 3 ) THEN
DBMS_OUTPUT.put_line( 'index_by_table(3) exists and the value is ' || index_by_table( 3 ) );
END IF;
//delete 10th element from a collection
nested_table.delete( 10 );
//delete elements 1 through 3 from a collection
nested_table.delete( 1, 3 );
index_by_table.delete( 10 );
DBMS_OUTPUT.put_line( 'nested_table.COUNT = ' || nested_table.COUNT );
DBMS_OUTPUT.put_line( 'index_by_table.COUNT = ' || index_by_table.COUNT );
DBMS_OUTPUT.put_line( 'nested_table.FIRST = ' || nested_table.FIRST );
DBMS_OUTPUT.put_line( 'nested_table.LAST = ' || nested_table.LAST );
DBMS_OUTPUT.put_line( 'index_by_table.FIRST = ' || index_by_table.FIRST );
DBMS_OUTPUT.put_line( 'index_by_table.LAST = ' || index_by_table.LAST );
DBMS_OUTPUT.put_line( 'nested_table.PRIOR(2) = ' || nested_table.PRIOR( 2 ) );
DBMS_OUTPUT.put_line( 'nested_table.NEXT(2) = ' || nested_table.NEXT( 2 ) );
DBMS_OUTPUT.put_line( 'index_by_table.PRIOR(2) = ' || index_by_table.PRIOR( 2 ) );
DBMS_OUTPUT.put_line( 'index_by_table.NEXT(2) = ' || index_by_table.NEXT( 2 ) );
//Trim last two elements
nested_table.TRIM( 2 );
//Trim last element
nested_table.TRIM;
DBMS_OUTPUT.put_line( 'nested_table.LAST = ' || nested_table.LAST );
DBMS_OUTPUT.put_line( '------------------- After deleted -------------------' );
//输出删除元素后联合数组的所有剩余元素
output:='';
FOR i IN index_by_table.FIRST .. index_by_table.LAST
LOOP
output := output || NVL( TO_CHAR( index_by_table( i ) ), 'NULL' ) || ' ';
END LOOP;
DBMS_OUTPUT.put_line( 'Element of Index_by_table are: ' || output );
output := '';
//输出删除元素后嵌套表的所有剩余元素
output:='';
FOR i IN nested_table.FIRST .. nested_table.LAST
LOOP
output := output || NVL( TO_CHAR( nested_table( i ) ), 'NULL' ) || ' ';
END LOOP;
DBMS_OUTPUT.put_line( 'Element of nested_table are: ' || output );
END;
--------------------------- Before deleted -----------------------------------------
Element of Index_by_table are: Value_1 Value_2 Value_3 Value_4 Value_5 Value_6 Value_7 Value_8 Value_9 Value_10
Element of nested_table are: 10 20 30 40 50 60 70 80 90 100
index_by_table(3) exists and the value is Value_3
nested_table.COUNT = 6 -->嵌套表使用了两次delete,分别是删除最后一个元素和删除第1到第3个元素,因此嵌套表的count输出为6
index_by_table.COUNT = 9 -->联合数组中删除了最后的一个元素,因此联合数组的count输出为9
nested_table.FIRST = 4 -->嵌套表删除了第1到第3个元素,因此其first变成4
nested_table.LAST = 9 -->嵌套表删除了最后一个元素,因此last变成9
index_by_table.FIRST = 1
index_by_table.LAST = 9
nested_table.PRIOR(2) = -->嵌套表的PRIOR(2),第2个元素的前一个(下标为1),由于1-3都被删除,且1之前没有任何元素,故为NULL
nested_table.NEXT(2) = 4 -->嵌套表2之后元素的下标,原本应该是3,由于3被删除,因此3被忽略,返回4
index_by_table.PRIOR(2) = 1
index_by_table.NEXT(2) = 3
nested_table.LAST = 7 -->nested_table.TRIM(2)与nested_table.TRIM总共删除了3个元素及占位符,故LAST为7。
--------------------------- After deleted -----------------------------------------
Element of Index_by_table are: Value_1 Value_2 Value_3 Value_4 Value_5 Value_6 Value_7 Value_8 Value_9
Element of nested_table are: 40 50 60 70
PL/SQL procedure successfully completed.
----------------------------------------------------------------------------------------------------------------------------
-->示例2
DECLARE
TYPE varray_type IS VARRAY(10) OF NUMBER;
varray varray_type := varray_type(1, 2, 3, 4, 5, 6);
PROCEDURE print_numlist( the_list varray_type ) IS output VARCHAR2( 128 );
BEGIN
FOR i IN the_list.FIRST .. the_list.LAST
LOOP
output := output || NVL( TO_CHAR( the_list( i ) ), 'NULL' ) || ' ';
END LOOP;
DBMS_OUTPUT.put_line( output );
END;
BEGIN
print_numlist( varray );
DBMS_OUTPUT.put_line( 'varray.COUNT = ' || varray.COUNT );
DBMS_OUTPUT.put_line( 'varray.LIMIT = ' || varray.LIMIT );
DBMS_OUTPUT.put_line( 'varray.FIRST = ' || varray.FIRST );
DBMS_OUTPUT.put_line( 'varray.LAST = ' || varray.LAST );
DBMS_OUTPUT.put_line( 'The maximum number you can use with ' || 'varray.EXTEND() is ' || ( varray.LIMIT - varray.COUNT ) );
varray.EXTEND( 2, 4 ); //将第4个元素的值复制2份,追加到集合尾部
DBMS_OUTPUT.put_line( 'varray.LAST = ' || varray.LAST );
DBMS_OUTPUT.put_line( 'varray(' || varray.LAST || ') = ' || varray( varray.LAST ) );
print_numlist( varray );
-- Trim last two elements
varray.TRIM( 2 );
DBMS_OUTPUT.put_line( 'varray.LAST = ' || varray.LAST );
END;
1 2 3 4 5 6 -->输出varray中的所有元素
varray.COUNT = 6
varray.LIMIT = 10 -->limit方法得到变长数组的最大容量
varray.FIRST = 1
varray.LAST = 6
The maximum number you can use with varray.EXTEND() is 4 -->得到可以extend的容量,即还可以保存4个元素
varray.LAST = 8 --> extend之后last的下标值为8
varray(8) = 4 -->第8个元素的值则为4
1 2 3 4 5 6 4 4 -->输出varray中的所有元素
varray.LAST = 6 -->由于使用了varray.TRIM( 2 ),所以last又变成了6
PL/SQL procedure successfully completed.
PL/SQL — 集合及常用方法的更多相关文章
- PL/SQL集合 ----- varrays
varrays可以再表,记录,对象定义中使用,类似于C中的数组. 1.定义varrays用作PL/SQL程序构造块. declare type integer_varray ) of integer; ...
- Oracle错误(包括PL/SQL)集合与修复
+-----------------------------------------------------------------------+ | 在本篇随笔中,仅根据个人经验累积错误进行描述 ...
- PL/SQL集合(一):记录类型(TYPE 类型名称 IS RECORD)
记录类型 利用记录类型可以实现复合数据类型的定义: 记录类型允许嵌套: 可以直接利用记录类型更新数据. 传统操作的问题 对于Oracle数据类型,主要使用的是VARCHAR2.NUMBER.DATE等 ...
- PL/SQL学习笔记之集合
一:PL/SQL集合 集合是一个有序且存有相同的类型数据的数据结构. PL/SQL提供了三种集合类型: 索引表(关联数组) 嵌套表 数组 二:索引表:一个索引表(也叫关联数组)是一组键 - 值对.每个 ...
- PL/SQL — 变长数组
PL/SQL变长数组是PL/SQL集合数据类型中的一种,其使用方法与PL/SQL嵌套表大同小异,唯一的区别则是变长数组的元素的最大个数是有限制的.也即是说变长数组的下标固定下限等于1,上限可以扩展.下 ...
- PL/SQL --> 动态SQL调用包中函数或过程
动态SQL主要是用于针对不同的条件或查询任务来生成不同的SQL语句.最常用的方法是直接使用EXECUTE IMMEDIATE来执行动态SQL语句字符串或字符串变量.但是对于系统自定义的包或用户自定的包 ...
- PL/SQL批处理语句(BULK COLLECT子句和FORALL语句)
Oracle为PL/SQL中的SQL相关功能提供了FORALL语句和BULK COLLECT子句,显著的增强了SQL相关功能.这两个语句一起被称作PL/SQL的批处理语句.Oracle为什么要提供这两 ...
- PL/SQL详细介绍,设置oracle相关
1. 实现参照完整性 指若两个表之间具有主从关系(即主外键关系),当删除主表数据时,必须确保相关的从表数据已经被删除. 当修改主表的主键列数据时,必须确保相关从表数据已经被修改.为了实现级 ...
- PL/SQL 训练13--plsql 优化
--数据缓存技术 --PGA和SGA---SGA:系统全局区域--PGA:Process Global Area是为每个连接到Oracle的用户进程保留的内存. ---PLSQL从PGA获取信息的速度 ...
随机推荐
- Debug 之 VS2010网站生成成功,但是发布失败
用vs做好了网站.清理解决方案和重新生成解决方案都可以.但是发布不能成功.发布不能成功,有错误还好,郁闷的是竟然没有错误提示. 解决方法: 1.发布文件夹权限问题.重新找个地方建立一个发布文件夹即可. ...
- Android打地鼠游戏源码带道具购买的Android游戏开发
这是一款基于安卓的打地鼠游戏,界面简洁,有level模式打地鼠和无尽模式打地鼠两种游戏模式,并可以通过商店使用金币进行道具的购买,道具可以让你更容易通关:同时金币可以在游戏通关的时候获取.工程中有较为 ...
- 简单理解前端web开发的MVC模式
随着前端Ajax兴起.前端开发工作进一步划分:js开发和ui页面制作.另外从整个前端项目的清晰明朗以可扩展性角度来看,MVC的应用也越来越必要,特别是对大的项目. 例如 需要给一个页面上的button ...
- RMI原理
一.分布式对象 在学习 RMI 之前,先来分布式对象(Distributed Object):分布式对象是指一个对象可以被远程系统所调用.对于 Java 而言,即对象不仅可以被同一虚拟机中的其他客户程 ...
- php中的匿名函数(Anonymous functions)和闭包函数(closures)
一:匿名函数 (在php5.3.0 或以上才能使用) php中的匿名函数(Anonymous functions), 也叫闭包函数(closures), 允许指定一个没有名称的函数.最常用的就是回调函 ...
- hackerrank Day15: Linked List
#include <iostream> #include <cstddef> using namespace std; class Node { public: int dat ...
- (原创)鸟哥linux学习script shell相关笔记
在使用鸟哥linux进行script shell学习的过程中碰到一些不太明白的知识点,在这里进行一些记录 1. [root@www scripts]# vi sh03.sh #!/bin/bash # ...
- hasLayout与Block formatting contexts的学习(上)
hasLayout与Block formatting contexts的学习 @(css BFC)[IE hasLayout|妙瞳] hasLayout是什么? haslayout 是Windows ...
- 第六章 jQuery操作表单
1.单行文本框的应用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// ...
- 转载--- SQL Server XML基础学习之<4>--XPath
T-SQL 支持用于查询 XML 数据类型的 XQuery 语言. XQuery 基于现有的 XPath 查询语言,并支持更好的迭代.更好的排序结果以及构造必需的 XML 的功能. 所以我们本章先 ...