Saturday, 7 February 2015

Bulk Collect In Oracle


Definition of Bulk Collect:- Bulk binds can improve the performance when loading collections from a queries. The BULK COLLECT INTO construct binds the output of the query to the collection. To test this create the following table.

below example will help you to understand how it will improve performance.

create a table to understand how bulk collection is working.

CREATE TABLE bulk_collect_test AS
SELECT owner,
       object_name,
       object_id

FROM   all_objects;

Below code will understand how normal code and bulk code will improve performance.

SET SERVEROUTPUT ON
DECLARE
  TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE;

  l_tab    t_bulk_collect_test_tab := t_bulk_collect_test_tab();
  l_start  NUMBER;
BEGIN
  -- Time a regular population.
  l_start := DBMS_UTILITY.get_time;

  FOR cur_rec IN (SELECT *
                  FROM   bulk_collect_test)
  LOOP
    l_tab.extend;
    l_tab(l_tab.last) := cur_rec;
  END LOOP;

  DBMS_OUTPUT.put_line('Regular (' || l_tab.count || ' rows): ' || 
                       (DBMS_UTILITY.get_time - l_start));
  
  -- Time bulk population.  
  l_start := DBMS_UTILITY.get_time;

  SELECT *
  BULK COLLECT INTO l_tab
  FROM   bulk_collect_test;

  DBMS_OUTPUT.put_line('Bulk    (' || l_tab.count || ' rows): ' || 
                       (DBMS_UTILITY.get_time - l_start));
END;
/
Regular (42578 rows): 66
Bulk    (42578 rows): 4

PL/SQL procedure successfully completed.

SQL>

we can see how much regular time has taken and bulk time has taken, it will improve more performance.Remember that collections are held in memory, so doing a bulk collect from a large query could cause a considerable performance problem

we can use by another method by using Limit option in bulk collections.This gives you the benefits of bulk binds, without hogging all the server memory. The following code shows how to chunk through the data in a large table.


SET SERVEROUTPUT ON
DECLARE
  TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE;

  l_tab t_bulk_collect_test_tab;

  CURSOR c_data IS
    SELECT *
    FROM bulk_collect_test;
BEGIN
  OPEN c_data;
  LOOP
    FETCH c_data
    BULK COLLECT INTO l_tab LIMIT 10000;
    EXIT WHEN l_tab.count = 0;

    -- Process contents of collection here.
    DBMS_OUTPUT.put_line(l_tab.count || ' rows');
  END LOOP;
  CLOSE c_data;
END;
/
10000 rows
10000 rows
10000 rows
10000 rows
2578 rows

PL/SQL procedure successfully completed.

SQL>

So we can see that with a LIMIT 10000 we were able to break the data into chunks of 10,000 rows, reducing the memory footprint of our application

from 10g on words PL/SQL compiler converts cursor FOR LOOPs into BULK COLLECTs with an array size of 100. 

Below example will give you clear idea how cursor for loop and bulk collection will work .

SET SERVEROUTPUT ON
DECLARE
  TYPE t_bulk_collect_test_tab IS TABLE OF bulk_collect_test%ROWTYPE;

  l_tab    t_bulk_collect_test_tab;

  CURSOR c_data IS
    SELECT *
    FROM   bulk_collect_test;

  l_start  NUMBER;
BEGIN
  -- Time a regular cursor for loop.
  l_start := DBMS_UTILITY.get_time;

  FOR cur_rec IN (SELECT *
                  FROM   bulk_collect_test)
  LOOP
    NULL;
  END LOOP;

  DBMS_OUTPUT.put_line('Regular  : ' || 
                       (DBMS_UTILITY.get_time - l_start));

  -- Time bulk with LIMIT 10.
  l_start := DBMS_UTILITY.get_time;

  OPEN c_data;
  LOOP
    FETCH c_data
    BULK COLLECT INTO l_tab LIMIT 10;
    EXIT WHEN l_tab.count = 0;
  END LOOP;
  CLOSE c_data;

  DBMS_OUTPUT.put_line('LIMIT 10 : ' || 
                       (DBMS_UTILITY.get_time - l_start));

  -- Time bulk with LIMIT 100.
  l_start := DBMS_UTILITY.get_time;

  OPEN c_data;
  LOOP
    FETCH c_data
    BULK COLLECT INTO l_tab LIMIT 100;
    EXIT WHEN l_tab.count = 0;
  END LOOP;
  CLOSE c_data;

  DBMS_OUTPUT.put_line('LIMIT 100: ' || 
                       (DBMS_UTILITY.get_time - l_start));

  -- Time bulk with LIMIT 1000.
  l_start := DBMS_UTILITY.get_time;

  OPEN c_data;
  LOOP
    FETCH c_data
    BULK COLLECT INTO l_tab LIMIT 1000;
    EXIT WHEN l_tab.count = 0;
  END LOOP;
  CLOSE c_data;

  DBMS_OUTPUT.put_line('LIMIT 1000: ' || 
                       (DBMS_UTILITY.get_time - l_start));
END;
/
Regular  : 18
LIMIT 10 : 80
LIMIT 100: 15
LIMIT 1000: 10

PL/SQL procedure successfully completed.

SQL> 

You can see from this example the performance of a regular FOR LOOP is comparable to a BULK COLLECT using an array size of 100.

Tuesday, 3 February 2015

On-Message Trigger form level in oracle form 11g:-  this is common for all form.

DECLARE
BEGIN
   
   IF MESSAGE_TYPE = 'FRM' AND MESSAGE_CODE = 40400 
   THEN
      IF frmpkg_export.v_user_selected = 'D' 
      THEN
         message('Deleted Successfully', NO_ACKNOWLEDGE);
      ELSE
         message('Saved Successfully', NO_ACKNOWLEDGE);
      END IF;
   ELSIF MESSAGE_CODE = 40401 or MESSAGE_CODE = 40102 or MESSAGE_CODE = 40405 or MESSAGE_CODE = 40404 
   THEN
      NULL;
   ELSE
   message(MESSAGE_TEXT);
   END IF;
   

END;


On-Error Triggger in Form level :- this is common for all form

DECLARE
BEGIN

   IF INSTR(DBMS_ERROR_TEXT, 'ORA-') = 1 AND DBMS_ERROR_CODE <> -1403
   THEN
      frmpkg_export.v_backend_err := 'Y';
   ELSIF  ERROR_CODE = 40401 OR ERROR_CODE = 40102 OR ERROR_CODE = 40405 OR ERROR_CODE = 41051
   THEN
   NULL;
   ELSE
     IF DBMS_ERROR_CODE <> 01403
     THEN
         message(ERROR_TEXT);
      END IF;
   END IF;
   
END;

Wednesday, 10 December 2014

Report Printing code in oracle forms 11g  With parameter

DECLARE          
   v_parameter_id PARAMLIST;
   v_report_title  VARCHAR2(200) := NULL;
   v_finyear_title VARCHAR2(200) := NULL;
   v_branch_title  VARCHAR2(200) := NULL;
   v_period_title  VARCHAR2(200) := NULL;
   v_report_code   fatempreport.report_code%TYPE;
   
  --Code added by CTE
  REPORT_ID      Report_object;

BEGIN

   IF frmpkg_general.data_check() = TRUE 
THEN
   
 v_parameter_id := get_parameter_list('REPOPARAMETER');
 
  IF NOT id_null(v_parameter_id) 
  THEN
      destroy_parameter_list(v_parameter_id);
  END IF;

 v_parameter_id := create_parameter_list('REPOPARAMETER');
 IF NOT id_null(v_parameter_id) 
 THEN
 
         add_Parameter(v_parameter_id, 'DESTYPE', TEXT_PARAMETER, null);
    add_Parameter(v_parameter_id, 'DESFORMAT', TEXT_PARAMETER, null);
    add_Parameter(v_parameter_id, 'DESNAME', TEXT_PARAMETER, null);
    add_Parameter(v_parameter_id, 'COPIES', TEXT_PARAMETER, 1);
  add_parameter(v_parameter_id, 'PARAMFORM', TEXT_PARAMETER, 'NO');
         add_parameter(v_parameter_id, 'P_COMPANY_NAME', TEXT_PARAMETER,                                :GLOBAL.g_company_name);
         Message('Processing, Please wait....', NO_ACKNOWLEDGE);
         SYNCHRONIZE;
      
      IF :PARAMETER.P_REPORT_TYPE = 'JOURNAL_PERIOD_WISE'
      THEN

         v_finyear_title := TO_CHAR(:report_block.txt_from_date,:GLOBAL.g_date_format) || ' - ' || TO_CHAR(:report_block.txt_to_date,:GLOBAL.g_date_format);
         v_branch_title := :GLOBAL.g_branch_name;
         v_report_title  :=  :report_block.txt_journal_name;
         v_period_title := TO_CHAR(:report_block.txt_from_date,:GLOBAL.g_date_format) || ' - ' || TO_CHAR(:report_block.txt_to_date,:GLOBAL.g_date_format);
add_parameter(v_parameter_id, 'P_BOOK_CODE',TEXT_PARAMETER, :report_block.lb_journal);
add_parameter(v_parameter_id,'P_BRANCH_CODE',TEXT_PARAMETER,:GLOBAL.g_branch_code);
add_parameter(v_parameter_id, 'P_BRANCH_TITLE', TEXT_PARAMETER, v_branch_title);
add_parameter(v_parameter_id,'P_FINYEAR_CODE',TEXT_PARAMETER,:GLOBAL.g_finyear_code);
add_parameter(v_parameter_id, 'P_FINYEAR_TITLE', TEXT_PARAMETER, v_finyear_title);
add_parameter(v_parameter_id,'P_FROM_DATE',TEXT_PARAMETER,:report_block.txt_from_date);
add_parameter(v_parameter_id, 'P_PERIOD_TITLE', TEXT_PARAMETER, v_period_title);
add_parameter(v_parameter_id, 'P_REPORT_TITLE', TEXT_PARAMETER, v_report_title);
add_parameter(v_parameter_id, 'P_VOUCHERTYPE', TEXT_PARAMETER, :report_block.txt_voucher_type); 
add_parameter(v_parameter_id, 'P_TO_DATE', TEXT_PARAMETER, :report_block.txt_to_date);
add_parameter(v_parameter_id, 'P_HIDE_CANCELLED', TEXT_PARAMETER, :report_block.chk_hide_cancelled);
    
REPORT_ID:=FIND_REPORT_OBJECT('REPOBJ');
                      SET_REPORT_OBJECT_PROPERTY(report_id,REPORT_FILENAME,'JournalPeriodWise');
                   web_report_xl(REPORT_ID, v_parameter_id);
      END IF;
         
         Message(' ');

  destroy_parameter_list(v_parameter_id);
 END IF;
 
   END IF;
END;

/*----------------------------Excel Print------------------*/
PROCEDURE WEB_REPORT_XL (REPID REPORT_OBJECT, PLID PARAMLIST)IS
  REPORT_JOB_ID     VARCHAR2(100);  
  REP_STATUS        VARCHAR2(100);  
  REPORTSERVERJOB   VARCHAR2(100);    
BEGIN  
SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_COMM_MODE,SYNCHRONOUS);
  SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_DESTYPE,CACHE);                
  SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_DESFORMAT,'SPREADSHEET');
SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_SERVER,'repserv');
  REPORT_JOB_ID := RUN_REPORT_OBJECT (REPID,PLID);  
  REP_STATUS := REPORT_OBJECT_STATUS (REPORT_JOB_ID);  
  IF REP_STATUS = 'FINISHED' THEN
WEB.SHOW_DOCUMENT ('http://100.100.11.100:8888/reports/rwservlet/getjobid='||substr(report_job_id,instr(report_job_id,'_',-1)+1)||'?server='||'repserv'||'+MIMETYPE=REPORTS/LOCAL','_self');
ELSE
    MESSAGE ('Report Failed with Error - ' || REP_STATUS);
  END IF;
END;

/*----------------------------Pdf Print------------------*/
PROCEDURE WEB_REPORT (REPID REPORT_OBJECT, PLID PARAMLIST)IS
  REPORT_JOB_ID     VARCHAR2(100);  
  REP_STATUS        VARCHAR2(100);  
  REPORTSERVERJOB   VARCHAR2(100);    
BEGIN  
SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_COMM_MODE,SYNCHRONOUS);
  SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_DESTYPE,CACHE);                
  SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_DESFORMAT,'PDF');
SET_REPORT_OBJECT_PROPERTY (REPID,REPORT_SERVER,'repserv');
  REPORT_JOB_ID := RUN_REPORT_OBJECT (REPID,PLID);  
  REP_STATUS := REPORT_OBJECT_STATUS (REPORT_JOB_ID);  
  IF REP_STATUS = 'FINISHED' THEN
WEB.SHOW_DOCUMENT ('http://100.100.100.11:8888/reports/rwservlet/getjobid='||substr(report_job_id,instr(report_job_id,'_',-1)+1)||'?server='||'repserv','_blank');
ELSE
    MESSAGE ('Report Failed with Error - ' || REP_STATUS);
  END IF;
END;


This is the code show how to auto refresh the values shown in the form it will auto refresh in every 5 min or given time and display the result.

1) you need to design the form as per your requirement
2)then you need to write code in two trigger
   a).WHEN-TIMER-EXPIRED
   b).WHEN-NEW-FORM-INSTANCE


a).WHEN-TIMER-EXPIRED :

DECLARE 
  timer_id  TIMER; 
  v_count NUMBER;
  CURSOR CFP 
  IS 
  select BMR.BMRBATCHMST_CODE,bmr.BMR_no,bmr.BMR_DATE,bmr.batch_code,IT.description pro_desc,decode(PROCESS_CATEGORY_STATUS,'INP','INPROGRESS - ') ||' UNDER - '||CM.description as status from BMRPRODUCTBATCHMASTER BMR,items IT,
  BMRBATCHPROCESSCATEGORY BPC,pdssstepcategory CM where bmr.product_code = it.sl_no and BPC.PROCESS_CATEGORY = CM.code
  and BPC.BMRBATCHMST_CODE = BMR.BMRBATCHMST_CODE and PROCESS_CATEGORY_STATUS = 'INP' order by BMR.BMRBATCHMST_CODE ;
BEGIN   
  timer_id := FIND_TIMER('refresh_timer');
   BEGIN

        GO_BLOCK('SHOWATTENDANCEDETAILS_BLOCK');
        Clear_Block(No_Validate);
       For mFP  IN CFP  LOOP 
        :showattendancedetails_block.BMRBATCHMST_CODE := mfp.BMRBATCHMST_CODE;
        :showattendancedetails_block.BMR_NO := mfp.BMR_no;
        :showattendancedetails_block.BMR_DATE := mfp.BMR_DATE;
        :showattendancedetails_block.BATCH_NO:= mfp.batch_code;
        :showattendancedetails_block.PRODUCT_NAME := mfp.pro_desc;
        :showattendancedetails_block.STATUS:= mfp.status;
          NEXT_RECORD;
        SYNCHRONIZE;
       END LOOP;
    
 END; 
END;

b).WHEN-NEW-FORM-INSTANCE

DECLARE
   v_count NUMBER;
   timer_id Timer; 
   five_sec NUMBER(5) := 15000;

BEGIN

timer_id := CREATE_TIMER('refresh_timer', five_sec,REPEAT);

EXCEPTION
   WHEN NO_DATA_FOUND 
   THEN
     exit_form(NO_VALIDATE);

END;


Here You can see Full output of the form 




















Saturday, 11 October 2014

In oracle forms i want to check in text field that is check whether user entered only number values or not for example phone number or tin number or zip code  so on....

Hear is the code to check whether user entered only numeric value or not using  PL/SQL code?

CREATE OR REPLACE FUNCTION NUMBER_CHECK (P_INPUT VARCHAR2)
    RETURN   NUMBER IS
    v_i      NUMBER := 0;
    v_length NUMBER := 0;
    v_select VARCHAR2(10);
    v_count  NUMBER := 0;
    v_return NUMBER;
    BEGIN
    v_length := length(P_INPUT);
    LOOP
     v_i :=  v_i + 1;
        SELECT  SUBSTR(p_input,v_i, 1)
        INTO    v_select
        FROM    dual;
        SELECT COUNT(*)
        INTO   v_count
        FROM   faaccountmaster
        WHERE REGEXP_LIKE (v_select,'[0-9]');
        IF  v_count = 0 THEN
            v_return  := 0;
            EXIT;
        ELSE
            v_return  := 1;
        END IF;
        IF v_i = v_length THEN
           EXIT;
        END IF;
    END LOOP;
    RETURN v_return;
    END NUMBER_CHECK;

Copyright © ORACLE-FORU - SQL, PL/SQL and ORACLE D2K(FORMS AND REPORTS) collections | Powered by Blogger
Design by N.Design Studio | Blogger Theme by NewBloggerThemes.com