关于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. 转:使用Tengine替代Nginx作为负载均衡服务器

    原文来自于:http://heylinux.com/archives/2938.html Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级 ...

  2. 随着visual studio 2013 发布.带来的一些变化

    1.asp.net a.在2013中, asp.net走向了统一.使用不同的asp.net 框架搭(web forms ,api, mvc )建混合应用 b.身份验证 无身份验证 个人用户账户 (窗体 ...

  3. 最牛「CSRF防护」,带你进入大虾们的圈子!

    简单理解 CSRF 什么是 CSRF? CSRF,通常称为跨站请求伪造,英文名 Cross-site request forgery 缩写 CSRF,是一种对网站的恶意攻击.一个跨站请求伪造攻击迫使登 ...

  4. (转载)JavaScript中定义变量

    (转载)http://blog.163.com/xuxiaoqianhz@126/blog/static/165190577201061594421870/ JavaScript中定义变量有两种方式: ...

  5. 【转】如何使用Unity创造动态的2D水体效果

    原文:http://gamerboom.com/archives/83080 作者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染 ...

  6. Linux process state codes

    Here are the different values that the s, stat and state output specifiers (header "STAT" ...

  7. nyoj 88 汉诺塔(一)【快速幂】

    汉诺塔(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度 ...

  8. Linux的定时任务

    分两种:一次性的定时任务.周期性的定时任务. 一次性的定时任务,又称at定时任务,命令为atd ,这里d是deamon的首字母,守护的意思,指守护进程:其实很多程序都是以d结尾,如httpd.memc ...

  9. ODBC 中遇到的错误

    直接贴解决办法的链接: http://zhidao.baidu.com/link?url=pyd2AiazzsZr4IlMpiCdXlLC6nnao908xmqmY9QI0yj8vIGCbRPRrqh ...

  10. Mybatis 控制台打出Sql-Log的设置

    首先工程中必须要有slf4j-log4j12-1.7.12.jar这个包,否则打不出来 而后工程中“log4j.properties”文件如下: log4j.appender.stdout=org.a ...