日期:2014-05-17  浏览次数:20893 次

嵌套游标性能太差,用什么代替呢?
如题

------解决方案--------------------
--//oracle 内存表(PL/SQL表)和数组

内存表:
> 怎样用PL/SQL表实现数组功能
PL/SQL表与其他过程化语言(如C语言)的一维数组类似。
实现PL/SQL表需要创建一个数据类型并另外进行变量说明。
Type <类型名> Is
Table Of <数据类型>
Index by Binary_Integer;

以下为一个例子:
Declare
Type Array_type is
Table Of Number
Index by Binary_Integer;
My_Array Array_type;
Begin
For I In 1..10 Loop
My_Array(I) := I*2;
End Loop;
For I In 1..10 Loop
Dbms_Output.Put_line(To_char(My_Array(I)));
End Loop;
End;

创建变量数组
创建一个数组类似于创建一个PL/SQL表,
因为首先需要声明类型,然后创建那种类型的一个变量。
但是又不同于PL/SQL表,一个数组是 "紧凑的 ",
不是 "松散的 "—在数组中没有 "空洞 ",空洞是指没有数据,这点与表完全不同。
还有, PL/SQL表事实上是没有界限的,而数组有一个明确的限制。
当创建一个数组时,数组为空,并且可以被测试为无效。
为了能够使用它,必须首先使用一个构造器初始化它,如下列代码所示:
--声明数组
Type Performers Is Varray(200) Of Varchar2(10);
Type Contacts Is Varray(200) Of prospects;
--定义数组
showLineup Performers( 'Juggler ', 'Singer ', 'Fire Swallower ');
myContacts Contacts := Contacts( 'John ', 'Mary ', 'Tito ');


--------------------------------------
pl/sql表的定义:
是一维的(说明pl/sql表只能有1列,于一维数组很相似)、无边界的(表行数没有限

制,动态增长,定义时并没有为其分配任何行)、由同类(pl/sql表只有1列,自然同

类)元素组成的稀疏(行被赋值后,该行才会存在于表中,行不必按顺序定义,可以给

表中的任何行赋值,如1行和100行赋值,他们中间可不给行赋值;VARRAY就不

行,VARRAY声明后即分配内存等待被使用)集合,并通过整数来索引(单索引模

式,BINARY_INTEGER来索引,充当主键,正负2的31次方减1的范围,可以为负数是因

为这个行好仅仅是一个数字而已,本身并不代表顺序)。

pl/sql表驻留在oracle server的私有pl/sql区域中。

由于pl/sql表只是pl/sql中定义的一种结构,并不是真实可访问的表(所以不存在

commit,rollback,select,insert,update,delete操作),RDBMS或SQL内核并不识

别他,所以对他的操作受到限制,比如pl/sql中的DML就不能操作他,因为DML要

提交给RDBMS来处理。
只能通过循环一次一行的浏览pl/sql表的内容。

1,声明pl/sql表
[语法:TYPE <table_type_name> IS TABLE OF <datatype> [NOT NULL] INDEX

BY BINARY_INTEGER;]


declare
type empRec is record
(
empNo varchar2(50),
empName varchar2(50),
empAge number
);
TYPE emptblTYPE IS TABLE OF empRec INDEX BY BINARY_INTEGER;
tEmp emptblTYPE;
CURSOR c_dept IS SELECT * from employee;

--//定义变量
EmpCount number;
MaxEmpNo number;
BEGIN
FOR curEmp IN c_dept LOOP
tEmp(c_dept%ROWCOUNT).empNo:=curEmp.No;
END LOOP;

select count(1),max(NO) into EmpCount,MaxEmpNo from employee;

For I In 1..EmpCount Loop
DBMS_OUTPUT.PUT_LINE(tEmp(I).empNo);
End Loop;

DBMS_OUTPUT.PUT_LINE( 'the maxNo is: '||MaxEmpNo);