Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, ATSH.

Asked: June 06, 2017 - 2:47 pm UTC

Last updated: June 07, 2017 - 10:30 am UTC

Version: 11G

Viewed 1000+ times

You Asked

Here is my code:
procedure load_cmpnt_history is

      cursor c1 is
      select --+rule
                h.ndc_emp_id
        , nvl(upper(h.cmpnt_id),'FAA00000') cmpnt_id
     , h.compl_dt
     , nvl(nvl(h.crs_grade,h.cmpl_stat),'OTHER') crs_grade
              , h.cmpl_stat
              , h.lst_upd_tstmp
              , h.cmpnt_typ    
              , h.rev_dt        
              , s.lob_cd
              , c.cmpnt_title  
     from lms_stud_cmpnt_hst h
              , app_reference.student_base_ref s
              , lms_cmpnt c
          where h.ndc_emp_id is not null
            and h.stud_id is not null
            and s.ndc_emp_id (+) = h.ndc_emp_id
            and h.cmpnt_id = c.cmpnt_id(+)
            and h.rev_dt = c.rev_dt(+)
            and h.cmpnt_typ = c.cmpnt_typ(+);

   r1 c1%rowtype;

      grade_temp varchar2(30);
      grade_type_temp varchar2(1);

      begin

         delete from cmpnt_history;

         sys.dbms_output.put_line(to_char(sysdate,'mm/dd/yyyy hh24:mi:ss'));
         
         for r1 in c1 loop

            begin            

            app_reference.retrieve_grade
               (r1.cmpl_stat,r1.crs_grade,grade_temp,grade_type_temp,r1.lob_cd);
               
         insert into cmpnt_history
         ( ndc_emp_id
      , cmpnt_id
               , cmpnt_type     
               , rev_dt       
      , compl_dt
      , crs_grade
               , cmpnt_title   
      , crs_grade_type
               , lst_upd_tstmp )
            values
         ( r1.ndc_emp_id
        , r1.cmpnt_id
               , r1.cmpnt_typ   
               , r1.rev_dt      
      , r1.compl_dt
      , grade_temp
               , r1.cmpnt_title  
      , grade_type_temp
               , r1.lst_upd_tstmp );

          exception when others then
                sql_code := sqlcode;
                sql_error := substr(sqlerrm,1,4000);
                insert into calculation_log
                   (table_name,oracle_errorcode,oracle_errormsg)
                values
                   ('CMPNT_HISTORY',sql_code,sql_error);              
             end;

         end loop;

         commit;

      exception
         when others then
      sql_code := sqlcode;
   sql_error := substr(sqlerrm,1,4000);
   err := 1;
            rollback;
      insert into calculation_log
      (table_name,oracle_errorcode,oracle_errormsg)
   values
      ('CMPNT_HISTORY',sql_code,sql_error);
   commit;

   end;


How can I incorporate bulk collect to make the insert much faster?

and Chris said...

It depends on whether you want to limit the rows bulk collected or not. But in either case you need to replace:

for r1 in c1 loop


And declare an array variable to hold the data. e.g.:

type cur_arr is table of c1%rowtype index by pls_integer;
arr cur_arr;


If you're happy with unlimited bulk collection, you can do something like:

select ...
bulk collect
into  arr
from  your_query


This can blow out your PGA if it returns a large number of rows. So you may want to limit the rows you fetch at a time with something like:

open c1;
loop
fetch c1 bulk collect into arr limit 100;
exit when arr.count = 0;

...

end loop;
close c1;


You can read more about bulk collect at:

http://www.oracle.com/technetwork/issue-archive/2008/08-mar/o28plsql-095155.html
http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

ATSH, June 07, 2017 - 1:25 pm UTC

Thank you so much. Really helpful.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library