Bulk_Collect 调用方式集锦

事先申明,本文所有示例都皆源于《Expert PL SQL Practices》这本电子书的第六章。小陈觉得在学习PLSQL的过程中,将来或许会用到,在此笔记一番。

正文如下:

  首先准备基础数据吧 HARDWARE 表。

  表结构如图所示:

  

 

  然后插入1,000,000条数据吧。这里不得不说,PLSQL里面,dual表的确帮助很大,当然T-SQL里面你也可以建一张辅助表的。这里用的Oracle SQL Developer自带的格式化功能,相当弱。

  

INSERT INTO HARDWARE

SELECT TRUNC(rownum/1000)+1 aisle,

  rownum item,

  'Description '

  ||rownum descr

FROM

  ( SELECT 1 FROM dual CONNECT BY level <= 1000

  ),

  ( SELECT 1 FROM dual CONNECT BY level <= 1000

  );

这里先说最古老的用法吧:

SET serveroutput ON;
cl scr;
DECLARE
  l_cursor INT := dbms_sql.open_cursor;
  l_num_row dbms_sql.number_table;
  l_exec         INT;
  l_fetched_rows INT;
BEGIN
  dbms_sql.parse( l_cursor, 'select item from hardware where item <= 1200', dbms_sql.native);
  dbms_sql.define_array(l_cursor,1,l_num_row,500,1);
  l_exec := dbms_sql.execute(l_cursor);
  LOOP
    l_fetched_rows := dbms_sql.fetch_rows(l_cursor);
    dbms_sql.column_value(l_cursor, 1, l_num_row);
    dbms_output.put_line('Fetched '||l_fetched_rows||' rows');
    EXIT
  WHEN l_fetched_rows < 500;
  END LOOP;
  dbms_sql.close_cursor(l_cursor);
END; 

 

上面的调用极不推荐,进入主题吧。

1.     Implicit Cursor

DECLARE

  l_descr hardware.descr%type;

BEGIN

  SELECT  descr

  INTO    l_descr

  FROM    hardware

  WHERE   aisle = 1

          AND item = 1;

END;


2.    
Explicit Fetch Calls 

DECLARE

  CURSOR c_tool_list

  IS

    SELECT descr FROM hardware WHERE aisle = 1 AND item BETWEEN 1 AND 500;

  l_descr hardware.descr%type;

BEGIN

  OPEN c_tool_list;

  LOOP

    FETCH c_tool_list INTO l_descr;

    EXIT

  WHEN c_tool_list%notfound;

  END LOOP;

  CLOSE c_tool_list;

END;


3.    
Implicit Fetch Calls 

BEGIN

  FOR i IN

  ( SELECT descr FROM hardware WHERE aisle = 1 AND item BETWEEN 1 AND 500

  )

  LOOP

    pl(i.descr);--<processing code FOR EACH row>

  END LOOP;

END;

BEGIN

  FOR i IN

  ( SELECT descr FROM hardware WHERE aisle = 1 AND item BETWEEN 1 AND 500

  )

  LOOP

    --<processing code for each row>

  END LOOP;

END;


4.    
Implicit Cursor BULK Mode 

DECLARE

type t_descr_list

IS

  TABLE OF hardware.descr%type;

  l_descr_list t_descr_list;

BEGIN

  SELECT descr bulk collect

  INTO l_descr_list

  FROM hardware

  WHERE aisle = 1

  AND item BETWEEN 1 AND 100;

END;

5.     Explicit Fetch Calls BULK Mode 

DECLARE

  CURSOR c_tool_list

  IS

    SELECT descr FROM hardware WHERE aisle = 1 AND item BETWEEN 1 AND 500;

type t_descr_list

IS

  TABLE OF c_tool_list%rowtype;

  l_descr_list t_descr_list;

BEGIN

  OPEN c_tool_list;

  FETCH c_tool_list bulk collect INTO l_descr_list;

  CLOSE c_tool_list;

END;

 

最后给点彩蛋吧,还是书中的内容。比如T-SQL处理XML,ORACLE不知道甩了它几条街呢。 

CREATE OR REPLACE type COMING_FROM_XML

AS

  object

  (

    COL1 INT,

    COL2 INT)
DECLARE

  source_xml xmltype;

  target_obj coming_from_xml;

BEGIN

  source_xml := xmltype('<DEMO>

<COL1>10</COL1>

<COL2>20</COL2>

</DEMO>');

  source_xml.toObject(target_obj);

  dbms_output.put_line( target_obj.COL1  || ',' || target_obj.COL2);

END;
DECLARE
  l_refcursor SYS_REFCURSOR;
  l_xmltype XMLTYPE;
BEGIN
  OPEN l_refcursor FOR SELECT aisle , item,descr FROM HARDWARE WHERE aisle = 1 AND item BETWEEN 1 AND 10;
  l_xmltype                                                               := XMLTYPE(l_refcursor);
  dbms_output.put_line(l_xmltype.getClobVal);
END;

DECLARE
  l_xmltype XMLTYPE;
BEGIN
  l_xmltype := dbms_xmlgen.getxmltype('SELECT aisle , item,descr FROM HARDWARE WHERE aisle = 1 AND item BETWEEN 1 AND 10' );
  dbms_output.put_line(l_xmltype.getClobVal);
END;

DECLARE
   l_xmltype XMLTYPE;
   l_ctx dbms_xmlgen.ctxhandle;
BEGIN
   l_ctx := dbms_xmlgen.newcontext('SELECT aisle , item,descr FROM HARDWARE WHERE aisle = 1 AND item BETWEEN 1 AND 10'
                                  );

   dbms_xmlgen.setrowsettag(l_ctx, 'HARDWARE'); 
   dbms_xmlgen.setrowtag(l_ctx, 'Store');

   l_xmltype := dbms_xmlgen.getXmlType(l_ctx) ;
   dbms_xmlgen.closeContext(l_ctx);

   dbms_output.put_line(l_xmltype.getClobVal);
End;

结语:小陈学习ORCALE时间不久,有的都是T-SQL功底。只从简洁上来说,还是觉得T-SQL好多了。如果以慈母严父来形容MS与ORACLE。那么前者绝对好妈妈,后者是坏爸爸。 

 

posted @ 2015-09-18 00:43  Jeffrey Chan  阅读(426)  评论(0编辑  收藏  举报