declare
   type sallist is table of test1.id%type;
   sals   sallist;
begin
   select id
   bulk collect into sals
     from test1
    where rownum <= 10;
end;
-------
请教bulk collect作用。
sals值怎样拿。

解决方案 »

  1.   

    我不知道你说作用是什么意思,其实代码写完了,从功能上应该知道作用是什么,我姑且理解你不知道这种原理在那里吧。你可能用过游标,我拿它跟游标对比一下你一般就明白了:1、游标是先确定SQL,然后FETCH一条,到数据库缓冲区或者数据文件中或者UNDO提取找到对应的数据块,如果你的数据量很大,或者这个游标被反复的调用,这首先造成的巨大的IO频繁交互、以及如果游标被重复调用就会成倍增长,另外若游标带有一定的排序机制,在运行时被当前SESSION修改,可能会导致一些错误,其次一种现在可能性很小的就是:其他SESSION修改了游标遍历的数据,此时数据在UNDO中(11g不是),若数据库参数配置不当或者过程运行时间过长,UNDO的数据可能会被冲掉,此时会报ORA-01555错误;这类问题处理办法是使用游标上使用FOR UPDATE,但是这会导致阻塞,弄得不好会导致一些性能问题,但是对于常用的操作你还是不用怕的,一般问题不大,面对大量数据你就要注意一点了。2、bulk collect是结果集直接放入一个内存数据,也就是多行数据,它的好处就是一次装载多行数据或者说IO一次可以实现多块读的方法,而上面如果数据不在数据缓冲区,就肯定是单块读;并且其数据的处理过程和其他SESSION无关,操作过程全部是内存中取数据;坏处是如果数据被修改了,它毫无察觉;其次,在运行完以前,这段内存不会被释放,若数据量很大,将会占用大量的BUFFER_CACHE。3、将游标和这种方式结合的方法,也就是游标每次FETCH的时候采用bulk collect 数据放入到内存数组中,并可以使用limit控制每次FETCH的数据量大小,根据数据一两次多块读的的量大致估量数据量,内存使用量也不会太大,但是一次可以读取多个数据块出来进行处理实际问题,另外循环内存数组,如果你每次循环只是做一个DML语句,如INSERT,那么使用FORALL的使用它将会自动采用批处理模式,更加提高性能。差不多就这些吧,也不知道是不是想问的问题,呵呵。
      

  2.   

    bulk collect子句的作用是批量取得数据,可以大大提高效率。它只适用于SELECT INTO语句,FETCH INTO语句和DML返回子句。
    要取得sals的值,可以这样:FOR i IN 1..sals.count LOOP
       v_param := sals(i);
       dbms_output.put_line(v_param);
    END LOOP;