关于PL/SQL中这三种数组的介绍,不想写了。转一篇日志吧……

链接:http://www.blogjava.net/decode360/archive/2008/08/08/280825.html

作者:decode360

补充一点:假如从first到last的遍历过程中,存在被删除的占位符,如果使用则会报错。可用Exists(下标)的方法来判断是否存在。不能用is null 来判断……

记录类型不能整体用null判断,我能想到并测试成功的方法是判断里面的NOT NULL字段(推荐主键)是否为null。

PLSQL学习(二) 数组专题
 
    PLSQL中提供了三种数据的形式,功能还是比较强大的。但是总的来说,PLSQL中的数组知识掌握最简单的那种,其他大致了解就可以了。因为从实际应用的角度来说,在PLSQL中用到数组的几率不是很大。这主要是由于PLSQL跟数据库的紧密结合特性所决定的,数据库的表可以很轻易得实现基本的数组功能。当然这是我个人的一点理解,不一定正确。下面是详细介绍
 
 
1、PLSQL中的数组共分三类:
 
I  - 嵌套表(Nested tables)

TYPE nested_type IS TABLE OF VARCHAR2 ( 30 ) [not null];

-- 值为 varchar2 的数组,下标为默认 int 

特征:可删除信息,下标不变
 
II - 变长数组(Variable-Sized Arrays)

TYPE Calendar IS VARRAY ( 366 ) OF NUMBER ;

--366 个 number 数组,下标 1-366( 不是 0-365)

特征:一般在可预知数组个数的情况下使用,类似其他语言的Array
 
III- 索引表(Associative Array) 

TYPE population_type IS TABLE OF NUMBER

INDEX BY VARCHAR2 ( 64 );

-- 下标是 varchar2 ,值是 number 的数组

特征:可使用不连续数字、负数、字符作为下标,长度大小可变
      在创建数组时便分配内存,无需之后申请
      index by 只能跟BINARY_INTEGER、PLS_INTEGER、VARCHAR2三种类型
 
 
2、数组中的赋值错误问题:

DECLARE

TYPE wordlist IS TABLE OF VARCHAR2 ( 5 );

words wordlist;

BEGIN

words( 1 )      := 10 ; --COLLECTION_IS_NULL, 未赋空间

words         := wordlist( 10 , 20 , 30 ); -- 进行赋值

words( 1 )      := 'yes' ; -- 正确

words( 2 )      := words( 1 ) || 'no' ; -- 正确

words( 3 )      := 'longer than 5 characters' ; --VALUE_ERROR ,字符过长

words( 'B' )    := 'dunno' ; --VALUE_ERROR ,下标错误

words( 4 )      := 'maybe' ; --SUBSCRIPT_BEYOND_COUNT ,下标超限

END ;

 
在声明 words wordlist; 之后数组未初始化,完全没有用处
必须进行初始化,如:
words := wordlist( 10 , 20 , 30 );--定值初始化;
words := wordlist();--空值初始化,任何数组必须先初始化;
words.extend(n);--末尾增加N位空间,不加N则为默认增加1位;
然后可以赋值
 
 
3、数组相关集合函数:
 
1、EXISTS(判断第i位是否存在)

IF courses.EXISTS(i) THEN

courses(i)    := new_course;

END IF ;

2、COUNT(数组中的元素个数)

FOR i IN 1 .. courses.COUNT LOOP ...

注意:COUNT会忽略已经被删除的元素

3、LIMIT(集合的最大容量)

IF (projects.COUNT + 15 ) < projects.LIMIT THEN ...

注意:LIMIT一般只对变长数组有效(其他两类均返回NULL)
 
4、FIRST和LAST(第一个和最后一个元素的下标)

FOR i IN courses.FIRST .. courses.LAST LOOP ...

注意:返回值是下标,而不是值!在遍历元素时,FIRST和LAST都会忽略被删除的元素
 
5、PRIOR和NEXT(返回索引为n的前驱/后驱下标)

n := courses.PRIOR(courses.FIRST);  --assigns NULL to n

注意:返回值是下标,而不是值!在遍历元素时,FIRST和LAST都会忽略被删除的元素
 
6、EXTEND(扩大集合容量)

courses.EXTEND( m , n ); --将第n个元素的值复制m份加到集合末端

注意:m默认为1,n默认为null,m包含被删除元素
 
7、TRIM(缩减集合容量)

courses.TRIM( 3 ); -- 与 extend 相反

 
8、DELETE(删除集合元素)

courses.DELETE      -- 删除全部

courses.DELETE( 2 )   -- 删除第 个元素

courses.DELETE( 2 , 5 ) -- 删除第 到第 个元素

注意:使用delete的时候必须要结合3中数组的不同特征!
 
 
4、Exception的类型及原因:
 

COLLECTION_IS_NULL         --- 调用一个空集合的方法 集合未被初始化

NO_DATA_FOUND                --- 下标索引指向一个被删除的元素,或是关联数组中不存在的元素

SUBSCRIPT_BEYOND_COUNT    --- 下标索引值超过集合中的元素个数

SUBSCRIPT_OUTSIDE_LIMIT --- 下标索引超过允许范围之外

VALUE_ERROR                  --- 下标索引值为空,或是不是指定的下标类型

 
 
5、关于数组的特有批量绑定ForAll
 
1、语法结构:

FORALL i IN pnums.FIRST .. pnums.LAST

INSERT INTO partno VALUES (pnums(i));   ---注意:不用再Loop

 
 
2、可使用%BULK_ROWCOUNT属性来计算FORALL语句所影响到的行数

IF SQL % BULK_ROWCOUNT ( 3 ) = 0 THEN ...

表示如果第3次操作没有对数据影响的行数为0话……

注意%BULK_ROWCOUNT的值是可以大于1的,比如批量插入等

 
3、使用%BULK_EXCEPTIONS属性来控制FORALL异常

DECLARE

TYPE numlist IS TABLE OF NUMBER ;

num_tab      numlist  := numlist( 10 , 0 , 11 , 12 , 30 , 0 , 20 , 199 , 2 , 0 , 9 , 1 );

ERRORS        NUMBER ;

dml_errors   EXCEPTION ;

PRAGMA EXCEPTION_INIT (dml_errors, - 24381 );

BEGIN

FORALL i IN num_tab.FIRST .. num_tab.LAST SAVE EXCEPTIONS

DELETE FROM emp

WHERE sal > 500000 / num_tab(i);

EXCEPTION

WHEN dml_errors THEN

    ERRORS     := SQL %BULK_EXCEPTIONS.COUNT;

DBMS_OUTPUT.put_line( 'Number of errors is ' || ERRORS );

FOR i IN 1 .. ERRORS LOOP

DBMS_OUTPUT.put_line(   'Error '

|| i

|| ' occurred during '

|| 'iteration '

|| SQL % BULK_EXCEPTIONS (i).ERROR_INDEX);

DBMS_OUTPUT.put_line(   'Oracle error is '

|| SQLERRM (- SQL % BULK_EXCEPTIONS (i).ERROR_CODE));

END LOOP ;

END ;

PL/SQL 嵌套表变长数组和索引表[转]的更多相关文章

  1. PL/SQL — 变长数组

    PL/SQL变长数组是PL/SQL集合数据类型中的一种,其使用方法与PL/SQL嵌套表大同小异,唯一的区别则是变长数组的元素的最大个数是有限制的.也即是说变长数组的下标固定下限等于1,上限可以扩展.下 ...

  2. oracle:变长数组varray,嵌套表,集合

    创建变长数组类型 ) );  这个变长数组最多可以容纳两个数据,数据的类型为 varchar2(50) 更改元素类型的大小或精度 可以更改变长数组类型和嵌套表类型 元素的大小. ALTER TYPE ...

  3. C++内存分配及变长数组的动态分配

    //------------------------------------------------------------------------------------------------ 第 ...

  4. GCC 中零长数组与变长数组

    前两天看程序,发现在某个函数中有下面这段程序: int n; //define a variable n int array[n]; //define an array with length n 在 ...

  5. C99新特性:变长数组(VLA)

    C99标准引入了变长数组,它允许使用变量定义数组各维.例如您可以使用下面的声明: ; ; double sales[rows][cols]; // 一个变长数组(VLA) 变长数组有一些限制,它必须是 ...

  6. c语言,变长数组

    下面这个结构体,可以在malloc的时候指定数据data的长度,这样的形式就是变长数组:typedef struct{ int data_len; char data[0];//或char data[ ...

  7. C99中的变长数组(VLA)

    处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: #define COLS 4 int sum3d(int ar[] ...

  8. C语言变长数组 struct中char data[0]的用法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用s ...

  9. C语言变长数组data[0]总结

    C语言变长数组data[0] 1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内 ...

随机推荐

  1. 10055 - Hashmat the Brave Warrior

    Problem A Hashmat the brave warrior Input: standard input Output: standard output Hashmat is a brave ...

  2. C语言 rand()函数的用法

    rand()(产生随机数) 相关函数 srand() 表头文件 #include<stdlib.h> 定义函数 int rand()(void) 函数说明 rand()会返回一随机数值,范 ...

  3. Netty高性能之道

    1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用.相比于 ...

  4. UIImageView之我的动画为什么停了?UIImageView, highLighted,animationImages

    如果你的动画总是停了!停了!停了!不管你想不想都停,这里有个参考,你可以看看!这只是一种可能性!!! 受最近看到段子影响,画风略诡异,不喜勿喷. 最近在“刻”动画!!! 为什么是“刻”,动画写了3周啊 ...

  5. UE编辑器加载格式化代码插件astyle

    UE 的格式化功能不强,自带的astyle版本陈旧,一般采用开源工具astyle来实现代码格式化. 1. 首先下载最新的astyle,因为ue自带的astyle版本太老,不支持空格.中文名等. 2. ...

  6. wpf 资源的重用

    资源的利用 1) Window.Resource <Window.Resource> <ImageBrush x:Key="TitleBrush" TileMod ...

  7. R语言 系统聚类分析1

    #聚类分析是一类将数据所研究对象进行分类的统计方法,这一类方法的共同特点是:#事先不知道类别的个数与结构 据以进行分类的数据是对象之间的相似性 或差异性数据#将这些相似(相异)性数据看成是对象之间的距 ...

  8. 邮件发送小demo

    //send email public static bool SendEmail() { //实例化发件人地址 MailAddress from = new MailAddress("aa ...

  9. 2013.08.23.diary

    Today, my baby called me.She said, she want to go abroad . And she wants me to go abroad too. I thin ...

  10. UCloud EIP 你真的懂得如何使用么? - SegmentFault

    UCloud EIP 你真的懂得如何使用么? - SegmentFault UCloud EIP 你真的懂得如何使用么?