Wednesday, March 19, 2014

Explain Bulk Collect and FORALL in Oracle with eamples?


Bulk Collect:-

One method of fetching data is an Oracle bulk collect. With Oracle bulk collect, the PL/SQL engine tells the SQL engine to collect many rows at once and place them in a collection. During an Oracle bulk collect, the SQL engine retrieves all the rows and loads them into the collection and switches back to the PL/SQL engine. The larger the number of rows you would like to collect with Oracle bulk collect, the more performance improvement you will see using an Oracle bulk collect.


Example:-

    DECLARE
    TYPE OBJECT_REC IS TABLE OF ALL_OBJECTS%ROWTYPE;
    OBJECT_REC1 OBJECT_REC;
    CURSOR C1 IS SELECT * FROM ALL_OBJECTS;
    BEGIN
        OPEN C1;
        FETCH C1 BULK COLLECT INTO OBJECT_REC1;
            FOR I IN 1..OBJECT_REC1.COUNT
            LOOP
                DBMS_OUTPUT.PUT_LINE(OBJECT_REC1(I).OBJECT_ID||CHR(9)||OBJECT_REC1(I).OBJECT_NAME);
            END LOOP;
    END;       
   


Note:-  
        Remember that collections are held in memory, so doing a bulk collect from a large query could cause a considerable performance problem. In actual fact you would rarely do a straight bulk collect in this manner. Instead you would limit the rows returned using the LIMIT clause and move through the data processing smaller chunks. 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.
       

Example:-

    DECLARE
    TYPE OBJECT_REC IS TABLE OF ALL_OBJECTS%ROWTYPE;
    OBJECT_REC1 OBJECT_REC;
    CURSOR C1 IS SELECT * FROM ALL_OBJECTS;
    BEGIN
        OPEN C1;
        LOOP
            FETCH C1 BULK COLLECT INTO OBJECT_REC1 LIMIT 1000;
            FOR I IN 1..OBJECT_REC1.COUNT
            LOOP
                DBMS_OUTPUT.PUT_LINE(OBJECT_REC1(I).OBJECT_ID||CHR(9)||OBJECT_REC1(I).OBJECT_NAME);
            END LOOP;
        EXIT WHEN OBJECT_REC1.COUNT=0;
        END LOOP;
    END;       
   

   
FORALL:-

The FORALL syntax allows us to bind the contents of a collection to a single DML statement, allowing the DML to be run for each row in the collection without requiring a context switch each time. To test bulk binds using records we first create a test table.   

The FORALL statement is not a loop; it is a declarative statement to the PL/SQL engine: “Generate all the DML statements that would have been executed one row at a time, and send them all across to the SQL engine with one context switch.”

INSERTs, UPDATEs, and DELETEs that use collections to change multiple rows of data very quickly.



Example:-

    CREATE OR REPLACE PROCEDURE XXC05_FORALL_EXAMPLE
    IS
        TYPE L_FORALL_TAB IS TABLE OF XXC05_ALL_OBJECTS%ROWTYPE;
        L_FORALL L_FORALL_TAB;
    CURSOR C1
    IS
        SELECT *
        FROM ALL_OBJECTS;
    BEGIN
        OPEN C1;
        LOOP
            FETCH C1 BULK COLLECT INTO L_FORALL LIMIT 10000;
            DBMS_OUTPUT.PUT_LINE(L_FORALL.COUNT||CHR(9)||'ROWS');
           
            FORALL I IN L_FORALL.FIRST..L_FORALL.COUNT
                INSERT INTO XXC05_ALL_OBJECTS VALUES L_FORALL(I);
        EXIT WHEN L_FORALL.COUNT=0;
        END LOOP;
       
        COMMIT;
       
        CLOSE C1;
    END XXC05_FORALL_EXAMPLE;






Wednesday, March 12, 2014

EXECUTE IMMEDIATE option for Dynamic SQL and PL/SQL


The EXECUTE IMMEDIATE statement executes a dynamic SQL statement or anonymous PL/SQL block. With the help of EXECUTE IMMEDIATE statement we execute DDL statement.

Syntax:-
        EXECUTE IMMEDIATE <SQL or SPL Commands>
        [INTO <variable list>]
        [USING <bind variable list>];

       
Example:-

BEGIN
    EXECUTE IMMEDIATE 'create table XXC05_TEST (ID NUMBER,NAME VARCHAR2(20))';
    EXECUTE IMMEDIATE 'drop table XXC05_TEST';
    EXECUTE IMMEDIATE 'create table XXC05_TEST (EMP_NAME VARCHAR2(10))';
END;       


DECLARE
 L_CNT    VARCHAR2(20);
BEGIN
 EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM EMPLOYEES'
   INTO L_CNT;
 DBMS_OUTPUT.PUT_LINE(L_CNT);
END;


Note:-
    To return value into a PL/SQL record type: The same option can be used for %rowtype variables also.

DECLARE
 TYPE EMPDTLREC IS RECORD (EMPNO  NUMBER(4),
                           ENAME  VARCHAR2(20),
                           DEPTNO  NUMBER(2));
 EMPDTL EMPDTLREC;
BEGIN
 EXECUTE IMMEDIATE 'SELECT EMPNO, ENAME, DEPTNO ' ||
                   'FROM EMP WHERE EMPNO = 7934'
   INTO EMPDTL;
END;



Note:-
    As useful as DDL and DML are, a database is not very useful if you can't get your data out. You can also use execute immediate to select your data back out.





How can we achieve multi-org functionality in R12 for custom tables?


 We can create custom view to org specific. If we set org then fetch data for a specific org.

    Step1:- Create table custom schema

            create table XXC05_TEST_ORG(org_id number,po_header_id number,agent_id number,type_loolup_code varchar2(20));
       
    Step2:- Create VIEW in APPS schema
   
            CREATE OR REPLACE VIEW XXC05_ORG AS SELECT * FROM nn.XXC05_TEST_ORG;
       
    Note:-     nn is a schema name in which we create table.

    Step3:- Execute belo code
   
            begin
                dbms_rls.add_policy(OBJECT_SCHEMA => 'APPS',OBJECT_NAME => 'XXC05_ORG',POLICY_NAME => 'ORG_SEC',POLICY_FUNCTION =>'MO_GLOBAL.ORG_SECURITY');
            end;
           
            or

            begin
                dbms_rls.add_policy(NULL,'XXC05_ORG','ORG_SEC',NULL,'MO_GLOBAL.ORG_SECURITY',NULL,FALSE,TRUE,FALsE,NULL,FALSE,NULL,NULL);
            end;

            or

            begin
                dbms_rls.add_policy(NULL,'XXC05_ORG','ORG_SEC',NULL,'MO_GLOBAL.ORG_SECURITY');
            end;
   
   
   
    Step4:- Insert data in custom view.
   
        insert into XXC05_ORG(
                            SELECT     org_id,
                                    po_header_id,
                                    agent_id,
                                    type_lookup_code
                            FROM po_headers_all
                            WHERE org_id in (916,204,201)
                            );
                           
                           
    Step5:- Commit

    Step6:- Now custom view is org specific view. First we set org then fetch data.
   
                           

Tuesday, March 11, 2014

P2P Cycle in Oracle Apps with Tables



   P2PCycle:-


  
  TABLES:-

REQUISITION:-
                        Navigation:- Purchasing, Vision Operation(USA) => Requisitions => Requisitions
1.       PO_REQUISITION_HEADERS_ALL
2.       PO_REQUISITION_LINES_ALL
3.       PO_REQ_DISTRIBUTIONS_ALL

     SELECT *
     FROM PO_REQUISITION_HEADERS_ALL prha,
          PO_REQUISITION_LINES_ALL prla,
          PO_REQ_DISTRIBUTIONS_ALL prda
     WHERE prha.REQUISITION_HEADER_ID = prla.REQUISITION_HEADER_ID   
     AND prla.REQUISITION_LINE_ID = prda.REQUISITION_LINE_ID
     AND SEGMENT1 = '14531' ;   -- Requisition Number

RFQ:-
       Navigation:- Purchasing, Vision Operation(USA) => RFQ’s and Quotations => RFQ’s
1.       PO_HEADERS_ALL
2.       PO_LINES_ALL
3.       PO_LINE_LOCATIONS_ALL
4.       PO_REF_VENDORS

SELECT *
FROM PO_HEADERS_ALL pha,
     PO_LINES_ALL pla,
     PO_LINE_LOCATIONS_ALL plla
WHERE pha.PO_HEADER_ID  = pla.PO_HEADER_ID
AND pha.ORG_ID  = pla.ORG_ID
AND pla.PO_HEADER_ID  = plla.PO_HEADER_ID
AND pla.PO_LINE_ID  = plla.PO_LINE_ID
AND pLa.ORG_ID  = plla.ORG_ID
AND pha.SEGMENT1 = ‘329’  -- RFQ Number
AND pha.TYPE_LOOKUP_CODE = 'RFQ';

 RFQ Supplier Information:-  PO_RFQ_VENDORS”
                  where po_header_id(PO_RFQ_VENDORS) link to po_header_id(PO_HEADERS_ALL).
      SELECT *
      FROM PO_RFQ_VENDORS
           WHERE PO_HEADER_ID = 114255;

QUOTATION:-
                         Navigation:- Purchasing, Vision Operation(USA) => RFQ’s and Quotations => Quotation
1.       PO_HEADERS_ALL
2.       PO_LINES_ALL
3.       PO_LINE_LOCATIONS_ALL

SELECT *
FROM PO_HEADERS_ALL pha,
     PO_LINES_ALL pla,
     PO_LINE_LOCATIONS_ALL plla
WHERE pha.PO_HEADER_ID  = pla.PO_HEADER_ID
AND pha.ORG_ID  = pla.ORG_ID
AND pla.PO_HEADER_ID  = plla.PO_HEADER_ID
AND pla.PO_LINE_ID  = plla.PO_LINE_ID
AND pLa.ORG_ID  = plla.ORG_ID
AND pha.SEGMENT1 = ‘531’   -- Quotation Number
AND pha.TYPE_LOOKUP_CODE = 'QUOTATION'; 
Note:- When you Approved Quotation and analysis it then data insert into
 “PO_QUOTATION_APPROVALS_ALL” table, where line_location_id link to line_location_id from PO_LINE_LOCATIONS_ALL table.


PURCHASE ORDER:-
        Navigation:- Purchasing, Vision Operation(USA) => Purchase Orders => Purchase Orders

1.       PO_HEADERS_ALL
2.       PO_LINES_ALL
3.       PO_LINE_LOCATIONS_ALL
4.       PO_DISTRIBUTIONS_ALL

SELECT *
          FROM PO_HEADERS_ALL pha,
               PO_LINES_ALL pla,
               PO_LINE_LOCATIONS_ALL plla,
               PO_DISTRIBUTIONS_ALL PDA
          WHERE pha.PO_HEADER_ID  = pla.PO_HEADER_ID
          AND pha.ORG_ID  = pla.ORG_ID
          AND pla.PO_HEADER_ID  = plla.PO_HEADER_ID
          AND pla.PO_LINE_ID  = plla.PO_LINE_ID
          AND pLa.ORG_ID  = plla.ORG_ID
          AND pha.PO_HEADER_ID  = pda.PO_HEADER_ID
          AND pla.PO_LINE_ID  = pda.PO_LINE_ID
          AND plla.LINE_LOCATION_ID  = pda.LINE_LOCATION_ID
          AND pla.ORG_ID  = pda.ORG_ID
         AND pha.segment1  = '7566';   -- PO Number


Receipt:-
                Navigation:- Purchasing, Vision Operation(USA) => Purchase Orders => Purchase Orders

1.       RCV_TRANSACTIONS
2.       RCV_SHIPMENT_HEADERS
3.       RCV_SHIPMENT_LINES

           SELECT *
           FROM RCV_TRANSACTIONS rt,
                RCV_SHIPMENT_HEADERS rsh,
                RCV_SHIPMENT_LINES rsl
           WHERE rt.SHIPMENT_HEADER_ID = rsh.SHIPMENT_HEADER_ID
           AND rt.SHIPMENT_LINE_ID = rsl.SHIPMENT_LINE_ID
          AND rsh.SHIPMENT_HEADER_ID = rsl.SHIPMENT_HEADER_ID
          AND rt.PO_HEADER_ID = pha.PO_HEADER_ID
          AND pha.segment1= '7566';   -- PO Number

AP INVOCE:-
            Navigation:- Payables, Vision Operatoon(USA) => Invoices => Entry => Invoices

1.       AP_INVOICES_ALL
2.       AP_INVOICE_LINES_ALL
3.       AP_INVOICE_DISTRIBUTIONS_ALL
       
        SELECT *
  FROM AP_INVOICES_ALL aia,
     AP_INVOICE_LINES_ALL aila,
     AP_INVOICE_DISTRIBUTIONS_ALL aida
  WHERE aia.INVOICE_ID = aila.INVOICE_ID
  AND aia.INVOICE_ID = aida.INVOICE_ID
  AND aila.LINE_NUMBER = aida.INVOICE_LINE_NUMBER
  AND aia.INVOICE_NUM = '19879-781';   -- Invoice Number

AP PAYMENT:-

            Navigation:- Payables, Vision Operatoon(USA) => Payments => Entry => Payments

1.        AP_CHECKS_ALL
2.       AP_PAYMENT_SCHEDULES
3.       AP_PAYMENT_HIST_DISTS

GL TABLES:-

1.       XLA_DISTRIBUTION_LINKS
2.       XLA_AE_HEADERS
3.       XLA_AE_LINES
4.       XLA_EVENTS
5.       XLA_TRANSACTION_ENTITIES
6.       GL_IMPORT_REFERENCES
7.       GL_JE_HEADERS
8.       GL_JE_LINES
9.       GL_JE_BATCHES
10.   GL_BALANCES       
SELECT XAL.*
       FROM XLA_DISTRIBUTION_LINKS xdl,
            XLA_AE_LINES xal,
            XLA_AE_LINES xah,
            XLA_EVENTS xe
       WHERE xdl.AE_HEADER_ID = xah.AE_HEADER_ID
       AND xdl.AE_HEADER_ID = xaL.AE_HEADER_ID
       AND xdl.AE_LINE_NUM = xal.AE_LINE_NUM
       AND xdl.EVENT_ID = xe.EVENT_ID;
       SELECT *
       FROM GL_IMPORT_REFERENCES gir,
            GL_JE_HEADERS gjh,
            GL_JE_LINES gjl,
            GL_JE_BATCHES gjb
        WHERE gir.JE_HEADER_ID = gjh.JE_HEADER_ID
        AND gir.JE_HEADER_ID = gjl.JE_HEADER_ID
        AND gir.JE_LINE_NUM = gjl.JE_LINE_NUM
        AND gir.JE_BATCH_ID = gjb.JE_BATCH_ID;


Link between XLA and GL tables:-

       SELECT *
       FROM XLA_DISTRIBUTION_LINKS xdl,
            XLA_AE_LINES xal,
            XLA_AE_LINES xah,
            XLA_EVENTS xe,
            GL_IMPORT_REFERENCES gir,
            GL_JE_HEADERS gjh,
            GL_JE_LINES gjl,
            GL_JE_BATCHES gjb
       WHERE xdl.AE_HEADER_ID = xah.AE_HEADER_ID
       AND xdl.AE_HEADER_ID = xaL.AE_HEADER_ID
       AND xdl.AE_LINE_NUM = xal.AE_LINE_NUM
       AND xdl.EVENT_ID = xe.EVENT_ID
       AND xal.GL_SL_LINK_ID = gir.GL_SL_LINK_ID
       AND xal.GL_SL_LINK_TABLE = gir.GL_SL_LINK_TABLE
       AND gir.JE_HEADER_ID = gjh.JE_HEADER_ID
       AND gir.JE_HEADER_ID = gjl.JE_HEADER_ID
       AND gir.JE_LINE_NUM = gjl.JE_LINE_NUM
       AND gir.JE_BATCH_ID = gjb.JE_BATCH_ID;