使用Oracle PL/SQL集合

问题描述:

我需要实现的目标是从游标中获取所有记录到集合中,以使用该游标中的数据填充表。 不幸的是,我无法理解如何从光标获取数据到数组中。 我尝试过批量收集,但没有办法。 extend关键字的含义是什么?如何从数组中获取数据?使用Oracle PL/SQL集合

我首先声明一个带有必要字段的记录。然后,我创建了一个这种类型的表格。然后我批量收集从光标到表格的所有内容。它似乎工作,但现在如何从该表中获取数据?

+6

是否有一个原因,你想选择数据放入一个数组放入表中?您可以将游标的结果直接插入表中,理想情况下使用insert into ... select from ...语法,这将更快,并且不需要数组。 –

+0

我同意Stephen ODonnell使用SQL直接插入行,因为它比使用PL/SQL游标更有效。请参阅http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9014.htm#i2145081 – Ollie

不确定为什么你在批量收集时遇到问题:它非常简单。当我们处理数万条记录时,它会变得稍微困难​​一点,但是您不会说这是否是一个因素。无论哪种方式,您都不需要使用批量收集扩展。

SQL> SQL> SQL> ed 
Wrote file afiedt.buf 

    1 declare 
    2  type r_tmp is record 
    3   (empno number 
    4   , deptno number 
    5   , sal number); 
    6  type nt_emp is table of r_tmp; 
    7  emp_recs nt_emp; 
    8 begin 
    9  select e.empno 
10    , e.deptno 
11    , e.sal 
12  bulk collect into emp_recs 
13  from emp e; 
14  dbms_output.put_line('no of recs selected = '||emp_recs.count); 
15  forall i in emp_recs.first..emp_recs.last 
16   insert into temp_emp 
17   values emp_recs(i); 
18  dbms_output.put_line('no of recs inserted = '||sql%rowcount); 
19* end; 
20/
no of recs selected = 17 
no of recs inserted = 17 

PL/SQL procedure successfully completed. 

SQL> 

正如你可以看到,从嵌套表的签名匹配表的项目是不在话下插入记录。另外,如果记录实际上与现有的表匹配,我们可以用%ROWTYPE语法来声明嵌套表,而不是使用%ROWTYPE语法。

1 declare 
    2  type nt_emp temp_emp%rowtype; 
    3  emp_recs nt_emp; 
    4 begin 

散装收集和FORALL更有效,正常RBAR实现,但他们仍然比较低迷纯SQL。所以通常我们只会使用这种构造,我们正在对数组进行一些中间数据操作,而这本身不能在SQL中完成。随着Oracle的SQL功能随着每个版本的增加而增加,找到这样的需求变得越来越少见。

您可以使用BULK COLLECT来填充一个数组(或在记录的pl/sql表中)。
这样:

set serveroutput on 
declare 
    type xyz is record(colA number , 
        colB Date) ; 
    type xyz_table is table of xyz; 

    p_xyz_table xyz_table ; 

begin 
    select level, sysdate+level 
      bulk collect into p_xyz_table 
     from dual 
     connect by level < 15 ; 
     dbms_output.put_line('records=>' || p_xyz_table.count); 
     FOR i IN 1 .. p_xyz_table.COUNT LOOP 
      dbms_output.put_line(' colA=> ' || p_xyz_table(i).colA || '; colB=>' || p_xyz_table(i).colB); 
     end loop ; 
end ; 
/

results: 
records=>14 
colA=> 1; colB=>23/11/11 09:20:00 
colA=> 2; colB=>24/11/11 09:20:00 
colA=> 3; colB=>25/11/11 09:20:00 
colA=> 4; colB=>26/11/11 09:20:00 
colA=> 5; colB=>27/11/11 09:20:00 
colA=> 6; colB=>28/11/11 09:20:00 
colA=> 7; colB=>29/11/11 09:20:00 
colA=> 8; colB=>30/11/11 09:20:00 
colA=> 9; colB=>01/12/11 09:20:00 
colA=> 10; colB=>02/12/11 09:20:00 
colA=> 11; colB=>03/12/11 09:20:00 
colA=> 12; colB=>04/12/11 09:20:00 
colA=> 13; colB=>05/12/11 09:20:00 
colA=> 14; colB=>06/12/11 09:20:00 

退房的文档@http://docs.oracle.com/cd/B10501_01/appdev.920/a96624/05_colls.htm,它已经来到了真正的方便,我过去。 (这也将回答你关于EXTEND的问题)

如果这不是你要找的,请发布一段代码来帮助解决问题。

+0

非常感谢!您的解决方案100%工作!像你这样解释,这一切听起来很清楚! :D问候,佩德罗 – Yaroze