Minggu, 11 Mei 2014

Bulk collect and forall

Delapan tahun freelance ternyata seperti halnya katak dalam tempurung, karena penyelesaian maslah biasanya bersifat shortterm yang penting bisa solve dalam sebuah kasus, tanpa lebih lanjut inspeksi kedalam teknik yang lebih baik lagi.

Salah satunya adalah terjadi ketika sebuah teknik kursor yang melibatkan proses DML, biasanya saya memakai teknik kuno (old fashion way), yaitu memakai cursor dengan row-by-row proses. Ketika di teliti oleh teman seperjuangan di AUS. Dia dapat menunjukkan cara terbaik. Contoh berikut adalah proses sebanyak 10.000 row

  • Cursor Teknik lama : Elapsed: 00:00:12.703
  • set timing on
    DECLARE
     CURSOR a_cur IS 
     SELECT *
        from forall_test;
     l_tab  a_cur%ROWTYPE;
    begin
      execute immediate 'TRUNCATE TABLE forall_test2';
      OPEN a_cur;
      loop
        fetch a_cur  into l_tab;
        exit when a_cur%notfound;  
          INSERT INTO forall_test2 (id, code, description)
          values (l_tab.id, l_tab.code, l_tab.description);         
      end loop;  
      close a_cur;
      commit;
    end;
    /
    
  • Cursor bulk collect : Elapsed: 00:00:11.281
  • set timing on
    DECLARE
     CURSOR a_cur IS 
     SELECT *
        from forall_test;
     TYPE myarray IS TABLE OF a_cur%ROWTYPE index BY PLS_INTEGER;
     l_tab myarray;
    begin
      execute immediate 'TRUNCATE TABLE forall_test2';
      OPEN a_cur;
      loop
        fetch a_cur  bulk collect into l_tab limit 1000;
        exit when l_tab.count = 0;
        for i in l_tab.first .. l_tab.last loop
          INSERT INTO forall_test2 (id, code, description)
          values (l_tab(i).id, l_tab(i).code, l_tab(i).description);
          
        end loop;    
        
      END LOOP;
      close a_cur;
    
        commit;
    END;
    /
    
  • Cursor bulk collect dan forall : Elapsed: 00:00:01.969
  • set timing on
    DECLARE
     CURSOR a_cur IS 
     SELECT *
        from forall_test;
    
     TYPE myarray IS TABLE OF a_cur%ROWTYPE index BY PLS_INTEGER;
     l_tab myarray;
    begin
      execute immediate 'TRUNCATE TABLE forall_test2';
      OPEN a_cur;
      loop
        fetch a_cur  bulk collect into l_tab limit 1000;
        exit when l_tab.count = 0;
        forall i in l_tab.first .. l_tab.last 
          INSERT INTO forall_test2 (id, code, description)
          values (l_tab(i).id, l_tab(i).code, l_tab(i).description);   
        
      END LOOP;
      close a_cur;
    
        commit;
    end;
    /
    
  • Tanpa Cursor bulk collect dan forall : Elapsed: 00:00:01.797
  • set timing on
    DECLARE
     TYPE myarray IS TABLE OF forall_test%ROWTYPE index BY PLS_INTEGER;
     l_tab myarray;
    begin
      execute immediate 'TRUNCATE TABLE forall_test2';
      select *
      bulk collect into l_tab 
      from forall_test;
       
        forall i in l_tab.first .. l_tab.last 
          INSERT INTO forall_test2 (id, code, description)
          values (l_tab(i).id, l_tab(i).code, l_tab(i).description);
        commit;
    END;
    /
    

Special Thanks to Chris Finney for point this out.
Source :
1. Bulk Binds (BULK COLLECT & FORALL) and Record Processing in Oracle.
2. PL/SQL Collections and Records.
3. Tuning PL/SQL Applications for Performance.

Kamis, 01 Mei 2014

Hidden treasure of Interactive Report

Salah satu feature terbaik dari APEX adalah Interactive Report. Pada posting kali ini saya akan membuka feature dari IR dalam hal query reference.

  • Feature query IR<OPERATOR>_<COLUMN_ALIAS>.
  • Salah satu yang sering kita pakai adalah IR_DEPARTMENT_ID artinya kita melakukan filter terhadap kolom department ID, IR by default: EQUAL. Ternyata banyak lagi operator yang bisa kita pakai dalam melakukan filter.
    Daftar valid operator
Operator Description
EQ Equals (this is the default)
NEQ Not equals
LT Less than
LTE Less than or equal to
GT Greater than
GTE Greater than or equal to
LIKE SQL 'like' operator
N is null
NN is not null
C Contains
NC not contains
IN SQL 'in' Operator
NIN SQL 'not in' Operator
    sumber : Advanced Interactive Report by David Peake.
     
  • URL reference terhadap saved report.
  • Jika kita memiliki beberapa saved report, maka kita bisa melakukan reference ke page tujuan dengan memilih apakah memakai saved report 1 atau yang lain dalam contoh : IR_REPORT_DEFAULT atau IR_REPORT_CHART.