Showing posts with label SQL Scripts. Show all posts
Showing posts with label SQL Scripts. Show all posts

Sunday, May 31, 2015

Dynmic Sorting Based SQL Query

select
 employee_number EMPNO,
 full_name NAME
from per_people_f
order by
  decode(:P2_ORDER_BY,'EMPNO',empno,null)
, decode(:P2_ORDER_BY,'NAME',name,null)
, decode(:P2_ORDER_BY,'EMPNO,FULL_NAME',empno,
 name,null)

Saturday, March 21, 2015

If you want to print a string vertically then use the following SQL Query


SELECT SUBSTR ('&&String', ROWNUM, 1)
FROM all_tables
WHERE ROWNUM <= LENGTH (TRIM ('&STRING'));

How To Send An SMS Using PL/SQL Code/Script



Sending An SMS Using A PL/SQL Code/Script:


Follow the simple steps below to send an sms using your cell phone through a pl/sql code.


1. Compile the below procedure on sql*plus


CREATE OR REPLACE PROCEDURE send_sms (
p_sender IN VARCHAR2,
p_recipient IN VARCHAR2,
p_message IN VARCHAR2
)
AS
mailcon UTL_SMTP.connection;
BEGIN
mailcon := UTL_SMTP.open_connection ('localhost');
UTL_SMTP.helo (mailcon, 'localhost');
UTL_SMTP.mail (mailcon, p_sender);
UTL_SMTP.rcpt (mailcon, p_recipient);
UTL_SMTP.DATA (mailcon,
'From: '
|| p_sender
|| UTL_TCP.crlf
|| 'To: '
|| p_recipient
|| UTL_TCP.crlf
|| 'Subject: SMS From Database'
|| UTL_TCP.crlf
|| p_message
);
UTL_SMTP.quit (mailcon);
END;


2. We need to execute the above procedure so as to send SMS. The systax is as follows:


exec SEND_SMS('nisheeth.exe@gmail.com', '9886012345@ideacellular.net','This is my first SMS');


Note: In place of the '9886012345@ideacellular.net' you need to provide your mobile number if your operator is Idea. You can refer the following list of mobile operator and the area of the service to use them for sending messages.


Andhra Pradesh AirTel-----------Mobile No@airtelap.com
Andhra Pradesh Idea Cellular-----Mobile No@ideacellular.net
Chennai Skycell/Airtel------------Mobile No@airtelchennai.com
Chennai RPG Cellular-------------Mobile No@rpgmail.net
Delhi Airtel-----------------------Mobile No@airtelmail.com
Delhi Hutch-----------------------Mobile No@delhi.hutch.co.in
Gujarat Airtel---------------------Mobile No@airtelmail.com
Gujarat Idea Cellular--------------Mobile No@ideacellular.net
Gujarat Celforce/Fascel-----------Mobile No@celforce.com
Goa Airtel-------------------------Mobile No@airtelmail.com
Goa BPL Mobile-------------------Mobile No@bplmobile.com
Goa Idea Cellular------------------Mobile No@ideacellular.net
Haryana Airtel--------------------Mobile No@airtelmail.com
Haryana Escotel-------------------Mobile No@escotelmobile.com
Himachal Pradesh Airtel-----------Mobile No@airtelmail.com
Karnataka Airtel-------------------Mobile No@airtelkk.com
Kerala Airtel-----------------------Mobile No@airtelkerala.com
Kerala Escotel---------------------Mobile No@escotelmobile.com
Kerala BPL Mobile-----------------Mobile No@bplmobile.com
Kolkata Airtel----------------------Mobile No @airtelkol.com
Madhya Pradesh Airtel-------------Mobile No@airtelmail.com
Maharashtra Airtel-----------------Mobile No@airtelmail.com
Maharashtra BPL Mobile-----------Mobile No@bplmobile.com
Maharashtra Idea Cellular----------Mobile No@ideacellular.net
Mumbai Airtel----------------------Mobile No@airtelmail.com
Mumbai BPL Mobile----------------Mobile No@bplmobile.com
Punjab Airtel-----------------------Mobile No@airtelmail.com
Pondicherry BPL Mobile------------Mobile No @bplmobile.com
Tamil Nadu Airtel-------------------Mobile No@airtelmail.com
Tamil Nadu BPL Mobile-------------Mobile No@bplmobile.com
Tamil Nadu Aircel-------------------Mobile No@airsms.com
UP (West) Escotel-------------------Mobile No@escotelmobile.com


NUMBER TO LETTERS CONVERTER FUNCTION



create or replace function spell_number( p_number in number )                                  
return varchar2                                                              
as                                                                           
    type myArray is table of varchar2(255);                                  
    l_str    myArray := myArray( '',                                         
                           ' thousand ', ' million ',                        
                           ' billion ', ' trillion ',                        
                           ' quadrillion ', ' quintillion ',                 
                           ' sextillion ', ' septillion ',                   
                           ' octillion ', ' nonillion ',                     
                           ' decillion ', ' undecillion ',                   
                           ' duodecillion ' );                               
                                                                             
    l_num   varchar2(50) default trunc( p_number );                          
    l_return varchar2(4000);                                                  
begin                                                                        
    for i in 1 .. l_str.count                                                
    loop                                                                     
        exit when l_num is null;                                             
                                                                             
        if ( substr(l_num, length(l_num)-2, 3) <> 0 )                        
        then                                                                 
           l_return := to_char(                                              
                           to_date(                                           
                            substr(l_num, length(l_num)-2, 3),               
                              'J' ),                                         
                       'Jsp' ) || l_str(i) || l_return;                      
        end if;                                                              
        l_num := substr( l_num, 1, length(l_num)-3 );                        
    end loop;                                                                 
                                                                             
    return l_return;                                                         
end;                                                                         
/


select spell_number( 12345678901234567890123456789012345678 )  from dual;
SPELL_NUMBER(12345678901234567890123456789012345678)
------------------------------------------------------------------------------

Twelve undecillion Three Hundred Forty-Five decillion Six Hundred Seventy-Eight nonillion Nine Hundred One octillion Two Hundred Thirty-Four septillion Five Hundred Sixty-Seven sextillion Eight Hundred Ninety quintillion One Hundred Twenty-Three quadrillion Four Hundred Fifty-Six trillion Seven Hundred Eighty-Nine billion Twelve million Three Hundred Forty-Five thousand Six Hundred Seventy-Eight

Tuesday, March 10, 2015

HR EMPLOYEE SALARY UPDATE API


PROCEDURE PRC_EMPSAL_UPDATE(RET_CODE IN VARCHAR2,RET_BUF IN VARCHAR2) IS
    LB_INV_NEXT_SAL_DATE_WARNING      BOOLEAN;
    LB_PROPOSED_SALARY_WARNING        BOOLEAN;
    LB_APPROVED_WARNING               BOOLEAN;
    LB_PAYROLL_WARNING                BOOLEAN;
    LN_PAY_PROPOSAL_ID                NUMBER;
    LN_OBJECT_VERSION_NUMBER          NUMBER;
    L_ASSIGNMENT_NUMBER              NUMBER;
    L_PROPOSAL_REASON             VARCHAR2(30);
    L_APPROVED                    VARCHAR2(10);
    L_DATE_TO                     DATE:= NULL;
    TOTAL_RECORDS                 NUMBER;
    ERROR_RECORDS                 NUMBER;  
    CURRENT_RECORDS               NUMBER;
    L_ERROR_MESSAGE               VARCHAR2(4000);
    L_PERSON_ID                   NUMBER;
    L_EFFECTIVE_DATE_VALID           NUMBER;
CURSOR STAGING_RECORDS IS
SELECT A.*,ROWID FROM HR_EMP_UPDATE_STAGING A WHERE UPDATE_STATUS IS NULL OR UPDATE_STATUS = 'E';
BEGIN
SELECT COUNT(*)INTO CURRENT_RECORDS FROM HR_EMP_UPDATE_STAGING A WHERE UPDATE_STATUS IS NULL OR UPDATE_STATUS = 'E';
FOR I IN STAGING_RECORDS LOOP
--INITIAL VALUES
L_ERROR_MESSAGE := NULL;
L_APPROVED := NULL;
LN_PAY_PROPOSAL_ID := NULL;
LN_OBJECT_VERSION_NUMBER := NULL;
--STATUS VALIDATIONS
IF I.STATUS = 'Approved' THEN
L_APPROVED :=  'Y';
ELSIF I.STATUS = 'Proposed' THEN
L_APPROVED :=  'N';
ELSE
L_APPROVED :=  NULL;
END IF;
BEGIN
SELECT PERSON_ID INTO L_PERSON_ID
   FROM PER_ALL_PEOPLE_F
      WHERE EMPLOYEE_NUMBER =I.EMPLOYEE_ID      -- ENTER EMPLOYEE NUMBER HERE TO FETCH PERSON_ID
        AND SYSDATE BETWEEN EFFECTIVE_START_DATE
                      AND EFFECTIVE_END_DATE;
DBMS_OUTPUT.PUT_LINE('L_PERSON_ID: '||L_PERSON_ID);
EXCEPTION
       WHEN OTHERS THEN
L_ERROR_MESSAGE:=  L_ERROR_MESSAGE||' '||SQLERRM||' *';
END;
BEGIN
SELECT ASSIGNMENT_ID INTO L_ASSIGNMENT_NUMBER       -- TO FETCH ASSIGNMENT_ID BASED ON PERSON_ID WHICH IS GENERATED FROM ABOVE QUERY
   FROM PER_ALL_ASSIGNMENTS_F
      WHERE PERSON_ID = L_PERSON_ID
        AND EFFECTIVE_START_DATE >=SYSDATE
        AND ROWNUM<2 p="">DBMS_OUTPUT.PUT_LINE('L_ASSIGNMENT_NUMBER: '||L_ASSIGNMENT_NUMBER);
EXCEPTION
       WHEN OTHERS THEN
L_ERROR_MESSAGE:=  L_ERROR_MESSAGE||' '||SQLERRM||' *';
END;
--TO GET PROPOSAL REASONS
BEGIN
SELECT LOOKUP_CODE INTO L_PROPOSAL_REASON FROM HR_LOOKUPS WHERE LOOKUP_TYPE = 'PROPOSAL_REASON' AND MEANING = I.PROPOSAL_REASON;
DBMS_OUTPUT.PUT_LINE('L_PROPOSAL_REASON: '||L_PROPOSAL_REASON);
EXCEPTION
       WHEN OTHERS THEN
L_ERROR_MESSAGE:=  L_ERROR_MESSAGE||' '||SQLERRM||' *';
END;
BEGIN
SELECT 1 INTO L_EFFECTIVE_DATE_VALID            -- EFFECTIVE DATE VALIDATION
   FROM PER_PAY_PROPOSALS
      WHERE ASSIGNMENT_ID = L_ASSIGNMENT_NUMBER
          HAVING I.EFFECTIVE_DATE > MAX(CHANGE_DATE);
DBMS_OUTPUT.PUT_LINE('L_EFFECTIVE_DATE_VALID: '||L_EFFECTIVE_DATE_VALID);
EXCEPTION
       WHEN OTHERS THEN
L_ERROR_MESSAGE:=  L_ERROR_MESSAGE||' '||SQLERRM||' *';
END;

IF L_ASSIGNMENT_NUMBER IS NOT NULL AND I.NEW_SALARY IS NOT NULL AND L_EFFECTIVE_DATE_VALID IS NOT NULL AND L_APPROVED IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE(' NEW SALARY: '||I.NEW_SALARY);
BEGIN
   HR_MAINTAIN_PROPOSAL_API.CRE_OR_UPD_SALARY_PROPOSAL
    (
       -- INPUT
         P_BUSINESS_GROUP_ID                   => FND_PROFILE.VALUE('PER_BUSINESS_GROUP_ID'),
         P_ASSIGNMENT_ID                       => L_ASSIGNMENT_NUMBER,
         P_CHANGE_DATE                         => I.EFFECTIVE_DATE,                 -- EFFECTIVE FROM DATE
         P_PROPOSAL_REASON                     => L_PROPOSAL_REASON,                -- PROPOSAL REASON
         P_PROPOSED_SALARY_N                   => I.NEW_SALARY,                     -- PROPOSED SALARY
         P_APPROVED                            => L_APPROVED,
         P_DATE_TO                       => L_DATE_TO,                      -- EFFECTIVE TO DATE
         -- OUTPUT
         P_PAY_PROPOSAL_ID                     => LN_PAY_PROPOSAL_ID,
         P_OBJECT_VERSION_NUMBER               => LN_OBJECT_VERSION_NUMBER,
         P_INV_NEXT_SAL_DATE_WARNING           => LB_INV_NEXT_SAL_DATE_WARNING,
         P_PROPOSED_SALARY_WARNING             => LB_PROPOSED_SALARY_WARNING,
         P_APPROVED_WARNING                    => LB_APPROVED_WARNING,
         P_PAYROLL_WARNING                     => LB_PAYROLL_WARNING
    );

   IF LN_PAY_PROPOSAL_ID IS NOT NULL THEN
      COMMIT;
      DBMS_OUTPUT.PUT_LINE(LN_PAY_PROPOSAL_ID||' FOR :'||L_ASSIGNMENT_NUMBER||' PERSON_ID');
      UPDATE HR_EMP_UPDATE_STAGING SET UPDATE_STATUS = 'S' WHERE ROWID = I.ROWID;
   ELSE
      UPDATE HR_EMP_UPDATE_STAGING SET UPDATE_STATUS = 'E', ERROR_MESSAGE = 'ERROR OUT FROM API EXECUTION'  WHERE ROWID = I.ROWID;
   END IF;
EXCEPTION
       WHEN OTHERS THEN
L_ERROR_MESSAGE:=  L_ERROR_MESSAGE||' '||SQLERRM||' *';
UPDATE HR_EMP_UPDATE_STAGING SET UPDATE_STATUS = 'E', ERROR_MESSAGE = L_ERROR_MESSAGE WHERE ROWID = I.ROWID;
END;

ELSE
      IF L_ASSIGNMENT_NUMBER IS NULL THEN
          L_ERROR_MESSAGE := L_ERROR_MESSAGE||'NO SUCH EMPLOYEE EXISTS *';
      END IF;
      IF L_EFFECTIVE_DATE_VALID IS NULL THEN
          L_ERROR_MESSAGE := L_ERROR_MESSAGE||'PLEASE PROVIDE CORRECT EFFECTIVE DATE *';
      END IF;
      IF I.NEW_SALARY IS NULL THEN
          L_ERROR_MESSAGE := L_ERROR_MESSAGE||'PLEASE PROVIDE CORRECT SALARY *';
      END IF;
      IF L_APPROVED IS NULL THEN
          L_ERROR_MESSAGE := L_ERROR_MESSAGE||'PLEASE PROVIDE CORRECT APPROVED STATUS *';
      END IF;

UPDATE HR_EMP_UPDATE_STAGING SET UPDATE_STATUS = 'E',ERROR_MESSAGE = L_ERROR_MESSAGE WHERE ROWID = I.ROWID;
FND_FILE.PUT_LINE(FND_FILE.LOG,'ERROR RECORD FOR EMPLOYEE ID : '||I.EMPLOYEE_ID||' '||L_ERROR_MESSAGE);
COMMIT;
END IF;
END LOOP;

SELECT COUNT(*) INTO TOTAL_RECORDS FROM HR_EMP_UPDATE_STAGING;
SELECT COUNT(*) INTO ERROR_RECORDS FROM HR_EMP_UPDATE_STAGING WHERE UPDATE_STATUS = 'E';
--VIEW LOG FOR THIS ERROR DATA
FND_FILE.PUT_LINE(FND_FILE.LOG, '---------------RECORD VALIDATION STATS-------------------');
FND_FILE.PUT_LINE(FND_FILE.LOG,'TOTAL NO. OF RECORDS : '||TOTAL_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.LOG,'CURRENT NO. OF RECORDS TO INSERT : '||CURRENT_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.LOG,'NO. OF RECORDS INSERTED : '||(CURRENT_RECORDS-ERROR_RECORDS));
FND_FILE.PUT_LINE(FND_FILE.LOG,'NO. OF RECORDS FAILED TO INSERT : '||ERROR_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.LOG, '---------------------------------------------------------');
FND_FILE.PUT_LINE(FND_FILE.LOG, 'UN-SUCCESSFUL');
--VIEW OUTPUT FILE FOR THIS DATA
FND_FILE.PUT_LINE(FND_FILE.OUTPUT, '---------------RECORD VALIDATION STATS-------------------');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'TOTAL NO. OF RECORDS : '||TOTAL_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'CURRENT NO. OF RECORDS TO INSERT : '||(TOTAL_RECORDS-ERROR_RECORDS));
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'NO. OF RECORDS INSERTED : '||(CURRENT_RECORDS-ERROR_RECORDS));
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'NO. OF RECORDS FAILED TO INSERT : '||ERROR_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.OUTPUT, '---------------------------------------------------------');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT, 'SUCCESSFUL');
EXCEPTION
       WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE(SQLERRM);
       
END PRC_EMPSAL_UPDATE;
/

HR EMPLOYEE ORGANIZATION UPDATE API




PROCEDURE PRC_EMP_ORG_UPDATE(RET_CODE IN VARCHAR2,RET_BUF IN VARCHAR2) IS
             
L_EFFECTIVE_DATE             DATE:=    NULL;
L_ASSIGNMENT_ID              NUMBER:=  NULL;
L_CORRECTION              BOOLEAN;
L_UPDATE                  BOOLEAN;
L_UPDATE_OVERRIDE            BOOLEAN;
L_UPDATE_CHANGE_INSERT       BOOLEAN;
LC_DT_UD_MODE                VARCHAR2(100):= NULL;
L_LOCATION_ID                NUMBER:=  NULL;
L_GRADE_ID                   NUMBER:=  NULL;
L_JOB_ID                  NUMBER:=  NULL;
L_PAYROLL_ID              NUMBER:=  NULL;
L_ORGANIZATION_ID            NUMBER:=  NULL;
L_EMPLOYEE_CATEGORY          VARCHAR2(100):= NULL;
L_POSITION_ID                NUMBER:=  NULL;
L_PEOPLE_GROUP_ID            NUMBER:=  NULL;
L_OBJ_VERSION_NUM            NUMBER:=  NULL;
L_SPECIAL_CEILING_STEP_ID    PER_ALL_ASSIGNMENTS_F.SPECIAL_CEILING_STEP_ID%TYPE;
L_GROUP_NAME              VARCHAR2(30);
L_EFFECTIVE_START_DATE       PER_ALL_ASSIGNMENTS_F.EFFECTIVE_START_DATE%TYPE;
L_EFFECTIVE_END_DATE            PER_ALL_ASSIGNMENTS_F.EFFECTIVE_END_DATE%TYPE;
L_ORG_NOW_NO_MANAGER_WARNING BOOLEAN;
L_OTHER_MANAGER_WARNING         BOOLEAN;
L_SPP_DELETE_WARNING            BOOLEAN;
L_ENTRIES_CHANGED_WARNING       VARCHAR2(30);
L_TAX_DISTRICT_CHANGED_WARN     BOOLEAN;
L_PERSON_ID                  NUMBER:=  NULL;
L_EFFECTIVE_DATE_VALID       NUMBER:=  NULL;
ERROR_MESSAGE1               VARCHAR2(4000):=NULL;
TOTAL_RECORDS                NUMBER;
CURRENT_RECORDS              NUMBER;
ERROR_RECORDS                NUMBER;
CURSOR STAGING_RECORDS IS
SELECT A.*,ROWID FROM EMP_ORG_UPDATE_STG A WHERE UPDATE_STATUS IS NULL OR UPDATE_STATUS = 'E';
BEGIN
SELECT COUNT(*) INTO CURRENT_RECORDS FROM EMP_SUPERVISOR_UPDATE_STG A WHERE UPDATE_STATUS IS NULL OR UPDATE_STATUS = 'E';
FOR I IN STAGING_RECORDS LOOP
DBMS_OUTPUT.PUT_LINE(I.EMPLOYEE_ID);
--INITIATION OF VARIABLES
L_PEOPLE_GROUP_ID         := NULL;
L_OBJ_VERSION_NUM         := NULL;
L_SPECIAL_CEILING_STEP_ID := NULL;
ERROR_MESSAGE1            := NULL;
-- TO GET PERSON_ID BASED ON EMPLOYEE_NUMBER FROM STAGING TABLE
BEGIN
SELECT PERSON_ID INTO L_PERSON_ID
   FROM PER_ALL_PEOPLE_F
      WHERE EMPLOYEE_NUMBER =I.EMPLOYEE_ID
        AND SYSDATE BETWEEN EFFECTIVE_START_DATE
                      AND EFFECTIVE_END_DATE;
DBMS_OUTPUT.PUT_LINE('L_PERSON_ID:'||L_PERSON_ID);
EXCEPTION
       WHEN OTHERS THEN
ERROR_MESSAGE1:= ERROR_MESSAGE1||' '||SQLERRM||' *';
END;

-- TO GET OBJECT_VERSION_NUMBER BASED ON PERSON_ID AND ACTIVE PERSON
BEGIN
SELECT MAX(OBJECT_VERSION_NUMBER) INTO L_OBJ_VERSION_NUM
   FROM PER_ALL_ASSIGNMENTS_F
      WHERE PERSON_ID = L_PERSON_ID
        AND SYSDATE BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE;
IF L_OBJ_VERSION_NUM IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE('L_OBJ_VERSION_NUM:'||L_OBJ_VERSION_NUM);
END IF;
EXCEPTION
       WHEN OTHERS THEN
ERROR_MESSAGE1:= ERROR_MESSAGE1||' '||SQLERRM||' *';
END;
-- TO FETCH THE ASSIGNMENT_ID BASED ON PERSON_ID
BEGIN
SELECT ASSIGNMENT_ID,EFFECTIVE_START_DATE,LOCATION_ID,GRADE_ID,JOB_ID,PAYROLL_ID,EMPLOYMENT_CATEGORY,POSITION_ID, PEOPLE_GROUP_ID
 INTO L_ASSIGNMENT_ID, L_EFFECTIVE_DATE, L_LOCATION_ID, L_GRADE_ID, L_JOB_ID, L_PAYROLL_ID, L_EMPLOYEE_CATEGORY, L_POSITION_ID, L_PEOPLE_GROUP_ID
   FROM PER_ALL_ASSIGNMENTS_F
      WHERE PERSON_ID = L_PERSON_ID
        AND SYSDATE BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
        AND OBJECT_VERSION_NUMBER = L_OBJ_VERSION_NUM;
DBMS_OUTPUT.PUT_LINE('L_ASSIGNMENT_ID:'||L_ASSIGNMENT_ID);
EXCEPTION
       WHEN OTHERS THEN
ERROR_MESSAGE1:= ERROR_MESSAGE1||' '||SQLERRM||' *';
END;

-- TO VALIDATE EFFECTIVE_DATE
IF I.EFFECTIVE_DATE >= L_EFFECTIVE_DATE THEN
L_EFFECTIVE_DATE_VALID := 1;
ELSE
L_EFFECTIVE_DATE_VALID := NULL;
END IF;
-- TO VALIDATE THE ORGANIZATION WHICH IS IN STAGING TABLE
BEGIN
SELECT ORGANIZATION_ID INTO L_ORGANIZATION_ID
   FROM HR_ALL_ORGANIZATION_UNITS
      WHERE NAME = I.NEW_ORGANIZATION;
DBMS_OUTPUT.PUT_LINE('L_ORGANIZATION_ID:'||L_ORGANIZATION_ID);
EXCEPTION
       WHEN OTHERS THEN
ERROR_MESSAGE1:= ERROR_MESSAGE1||' '||SQLERRM||' *';
END;

--       AND BUSINESS_GROUP_ID = 202;
IF L_PERSON_ID IS NOT NULL AND L_OBJ_VERSION_NUM IS NOT NULL AND L_ASSIGNMENT_ID IS NOT NULL AND L_EFFECTIVE_DATE_VALID IS NOT NULL AND L_ORGANIZATION_ID IS NOT NULL THEN
BEGIN
DT_API.FIND_DT_UPD_MODES
   (    P_EFFECTIVE_DATE                  => I.EFFECTIVE_DATE,
        P_BASE_TABLE_NAME                 => 'PER_ALL_ASSIGNMENTS_F',
        P_BASE_KEY_COLUMN                 => 'ASSIGNMENT_ID',
        P_BASE_KEY_VALUE                  => L_ASSIGNMENT_ID,
         -- OUTPUT DATA ELEMENTS
         -- --------------------------------
         P_CORRECTION                     => L_CORRECTION,
         P_UPDATE                         => L_UPDATE,
         P_UPDATE_OVERRIDE                => L_UPDATE_OVERRIDE,
         P_UPDATE_CHANGE_INSERT           => L_UPDATE_CHANGE_INSERT
     );

   IF ( L_UPDATE_OVERRIDE = TRUE OR L_UPDATE_CHANGE_INSERT = TRUE )
   THEN
       -- UPDATE_OVERRIDE
       LC_DT_UD_MODE := 'UPDATE_OVERRIDE';
   END IF;
  IF ( L_CORRECTION = TRUE )
  THEN
      -- CORRECTION
     LC_DT_UD_MODE := 'CORRECTION';
  END IF;
  IF ( L_UPDATE = TRUE )
  THEN
      -- UPDATE
      LC_DT_UD_MODE := 'UPDATE';
   END IF;
  DBMS_OUTPUT.PUT_LINE('MODE: '||LC_DT_UD_MODE);
--WE NEED TO PROVIDE COMBINATIONS OF POSITION VALUES, JOB VALUES AND ORGANIZATION VALUES WHICH ARE LOCATED IN PER_POSITIONS.
HR_ASSIGNMENT_API.UPDATE_EMP_ASG_CRITERIA
 (
 -- INPUT DATA ELEMENTS
  P_EFFECTIVE_DATE                              => I.EFFECTIVE_DATE,
  P_DATETRACK_UPDATE_MODE                    => LC_DT_UD_MODE,
  P_ASSIGNMENT_ID                               => L_ASSIGNMENT_ID,
  P_LOCATION_ID                                 => L_LOCATION_ID,
  P_GRADE_ID                                    => L_GRADE_ID,
  P_JOB_ID                                      => L_JOB_ID,
  P_PAYROLL_ID                                  => L_PAYROLL_ID,
  P_ORGANIZATION_ID                             => L_ORGANIZATION_ID,   --NEW ORG_ID
  P_EMPLOYMENT_CATEGORY                         => L_EMPLOYEE_CATEGORY,
  P_POSITION_ID                           => L_POSITION_ID,
  -- OUTPUT DATA ELEMENTS
  P_PEOPLE_GROUP_ID                             => L_PEOPLE_GROUP_ID,
  P_OBJECT_VERSION_NUMBER                   => L_OBJ_VERSION_NUM,
  P_SPECIAL_CEILING_STEP_ID                     => L_SPECIAL_CEILING_STEP_ID,
  P_GROUP_NAME                                  => L_GROUP_NAME,
  P_EFFECTIVE_START_DATE                        => L_EFFECTIVE_START_DATE,
  P_EFFECTIVE_END_DATE                          => L_EFFECTIVE_END_DATE,
  P_ORG_NOW_NO_MANAGER_WARNING               => L_ORG_NOW_NO_MANAGER_WARNING,
  P_OTHER_MANAGER_WARNING                       => L_OTHER_MANAGER_WARNING,
  P_SPP_DELETE_WARNING                          => L_SPP_DELETE_WARNING,
  P_ENTRIES_CHANGED_WARNING                  => L_ENTRIES_CHANGED_WARNING,
  P_TAX_DISTRICT_CHANGED_WARNING             => L_TAX_DISTRICT_CHANGED_WARN
 );

 DBMS_OUTPUT.PUT_LINE(L_EFFECTIVE_START_DATE);
 IF L_EFFECTIVE_START_DATE IS NOT NULL THEN
 UPDATE EMP_ORG_UPDATE_STG   SET UPDATE_STATUS = 'S' WHERE ROWID = I.ROWID;
 COMMIT;
 ELSE
 UPDATE EMP_ORG_UPDATE_STG   SET UPDATE_STATUS = 'E', ERROR_MESSAGE = ERROR_MESSAGE1||' UNKNOWN ERROR FROM API *' WHERE ROWID = I.ROWID;
 COMMIT;
 END IF;

EXCEPTION WHEN OTHERS THEN                                                              
ERROR_MESSAGE1:=   ERROR_MESSAGE1||SQLERRM||' *';
UPDATE EMP_ORG_UPDATE_STG SET UPDATE_STATUS = 'E', ERROR_MESSAGE = ERROR_MESSAGE1||' *' WHERE ROWID = I.ROWID;
COMMIT;
END;
ELSE
   IF L_PERSON_ID IS NULL THEN
   ERROR_MESSAGE1:= ERROR_MESSAGE1||'NO SUCH EMPLOYEE EXISTS *';
   END IF;
   IF L_ASSIGNMENT_ID IS NULL THEN
   ERROR_MESSAGE1:= ERROR_MESSAGE1||'NO SUCH ASSIGNMENT EXISTS *';
   END IF;
   IF I.EFFECTIVE_DATE IS NULL OR L_EFFECTIVE_DATE_VALID IS NULL THEN
   ERROR_MESSAGE1:= ERROR_MESSAGE1||'PLEASE PROVIDE CORRECT EFFECTIVE DATE *';
   END IF;
   IF L_OBJ_VERSION_NUM IS NULL THEN
   ERROR_MESSAGE1:= ERROR_MESSAGE1||'NO ACTIVE ASSIGNMENTS AVAILABLE FOR THIS EMPLOYEE *';
   END IF;
UPDATE EMP_ORG_UPDATE_STG SET UPDATE_STATUS = 'E', ERROR_MESSAGE = ERROR_MESSAGE1 WHERE ROWID = I.ROWID;
COMMIT;
END IF;
END LOOP;
SELECT COUNT(1) INTO TOTAL_RECORDS FROM EMP_ORG_UPDATE_STG;
SELECT COUNT(1) INTO ERROR_RECORDS FROM EMP_ORG_UPDATE_STG WHERE UPDATE_STATUS = 'E';
--VIEW LOG FOR THIS ERROR DATA
FND_FILE.PUT_LINE(FND_FILE.LOG, '---------------RECORD VALIDATION STATS-------------------');
FND_FILE.PUT_LINE(FND_FILE.LOG,'TOTAL NO. OF RECORDS : '||TOTAL_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.LOG,'CURRENT NO. OF RECORDS TO INSERT : '||CURRENT_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.LOG,'NO. OF RECORDS INSERTED : '||(CURRENT_RECORDS-ERROR_RECORDS));
FND_FILE.PUT_LINE(FND_FILE.LOG,'NO. OF RECORDS FAILED TO INSERT : '||ERROR_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.LOG, '---------------------------------------------------------');

--VIEW OUTPUT FILE FOR THIS DATA
FND_FILE.PUT_LINE(FND_FILE.OUTPUT, '---------------RECORD VALIDATION STATS-------------------');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'TOTAL NO. OF RECORDS : '||TOTAL_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'CURRENT NO. OF RECORDS TO INSERT : '||(TOTAL_RECORDS-ERROR_RECORDS));
FND_FILE.PUT_LINE(FND_FILE.LOG,'NO. OF RECORDS INSERTED : '||(CURRENT_RECORDS-ERROR_RECORDS));
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'NO. OF RECORDS FAILED TO INSERT : '||ERROR_RECORDS);
FND_FILE.PUT_LINE(FND_FILE.OUTPUT, '---------------------------------------------------------');
EXCEPTION
       WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE(SQLERRM);
END PRC_EMP_ORG_UPDATE;
/

How to Convert the Column To Row in Table


SELECT      (SELECT   'Manager Note - '||APPROVER_COMMENTS
               FROM   < Table Name >
              WHERE   approval_seq = 1 AND leave_req_id = :p_leave_req_id)
         || ' '
         || (SELECT  'HR Note - ' || APPROVER_COMMENTS
               FROM   < Table Name >               WHERE   approval_seq = 2 AND leave_req_id = :p_leave_req_id) mana_hr_note
--  INTO   l_man_hr_note
  FROM   DUAL;
 
 
  This leave request approve by Elangovan Ragavan.. Approved by Arun
 
 
select user_id,listagg (login_id, ',') WITHIN GROUP (ORDER BY login_id) login_id from (select user_id,login_id from fnd_logins
where SESSION_NUMBER < (200)
and user_id in (1179,1178)
) group by user_id

select listagg (APPROVER_COMMENTS, ',') WITHIN GROUP (ORDER BY APPROVER_COMMENTS) login_id
from < Table Name >   where leave_req_id = p_leave_req_id

select listagg (APPROVER_COMMENTS, ',') WITHIN GROUP (ORDER BY approval_seq) login_id
from < Table Name >where leave_req_id = :p_leave_req_id

Saturday, February 14, 2015

Cursors And Bulk Collect


CURSORS
Cursor is a pointer to memory location which is called as context area which contains the information necessary for processing, including the number of rows processed by the statement, a pointer to the parsed representation of the statement, and the active set which is the set of rows returned by the query.
Cursor contains two parts
Header
Body
Header includes cursor name, any parameters and the type of data being loaded.
Body includes the select statement.
Ex:
Cursor c(dno in number) return dept%rowtype is select *from dept;
In the above
Header – cursor c(dno in number) return dept%rowtype
Body – select *from dept
CURSOR TYPES
Implicit (SQL)
Explicit
Parameterized cursors
REF cursors
Explicit Cursor: The set of rows returned by a query can consist of zero, one, or multiple rows, depending on how many rows meet your search criteria. When a query returns multiple rows, you can explicitly define a cursor to process the rows. You use three commands to control the cursor:
CURSOR STAGES
Open
Fetch
Close
Implicit Cursors: ORACLE implicitly opens a cursor to process each SQL statement not associated with an explicitly declared cursor.PL/SQL lets you refer to the most recent implicit cursor as the SQL” cursor. So, although you cannot use the OPEN,
FETCH, and CLOSE statements to control an implicit cursor, you can still use cursor attributes to access information about the most recently executed SQL statement.

CURSOR ATTRIBUTES
%found
%notfound
%rowcount
%isopen
%bulk_rowcount
%bulk_exceptions
CURSOR DECLERATION
Syntax:
Cursor is select statement;
Ex:
Cursor c is select *from dept;
CURSOR LOOPS
Simple loop
While loop
For loop
SIMPLE LOOP
Syntax:
Loop
Fetch into ;
Exit when % notfound;
;
End loop;
Ex:
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
<span style="color: #3366ff;"><em>DECLARE
     cursor c is select * from student;
     v_stud student%rowtype;
BEGIN
     open c;
     loop
        fetch c into v_stud;
        exit when c%notfound;
        dbms_output.put_line('Name = ' || v_stud.name);
     end loop;
     close c;
END;</em></span>
Output:
Name = saketh
Name = srinu
Name = satish
Name = sudha
WHILE LOOP
Syntax:
While % found loop
Fetch nto ;
;
End loop;
Ex:
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
<span style="color: #3366ff;"><em>DECLARE
     cursor c is select * from student;
     v_stud student%rowtype;
BEGIN
     open c;
     fetch c into v_stud;
     while c%found loop
          fetch c into v_stud;
          dbms_output.put_line('Name = ' || v_stud.name);
     end loop;
     close c;
END;</em></span>
Output:
Name = saketh
Name = srinu
Name = satish
Name = sudha
FOR LOOP
Syntax:
for in loop
;
End loop;
Ex:
PgSQL
1
2
3
4
5
6
7
<span style="color: #3366ff;"><em>DECLARE
     cursor c is select * from student;
BEGIN
     for v_stud in c loop
         dbms_output.put_line('Name = ' || v_stud.name);
     end loop;
END;</em></span>
Output:
Name = saketh
Name = srinu
Name = satish
Name = sudha
PARAMETARIZED CURSORS
This was used when you are going to use the cursor in more than one place with different values for the same where clause.
Cursor parameters must be in mode.
Cursor parameters may have default values.
The scope of cursor parameter is within the select statement.
Ex:
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<span style="color: #3366ff;"><em>DECLARE
         cursor c(dno in number) is select * from dept where deptno = dno;
         v_dept dept%rowtype;
      BEGIN
         open c(20);
         loop
             fetch c into v_dept;
             exit when c%notfound;
            dbms_output.put_line('Dname = ' || v_dept.dname || ' Loc = ' || v_dept.loc);
         end loop;
         close c;
     END;
Output:
     Dname = RESEARCH Loc = DALLAS</em></span>

PACKAGED CURSORS WITH HEADER IN SPEC AND BODY IN PACKAGE BODY
Cursors declared in packages will not close automatically.
In packaged cursors you can modify the select statement without making any changes to the cursor header in the package specification.
Packaged cursors with must be defined in the package body itself, and then use it as global for the package.
You can not define the packaged cursor in any subprograms.
Cursor declaration in package with out body needs the return clause.
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<span style="color: #3366ff;"><em>Ex1:
CREATE OR REPLACE PACKAGE PKG IS
                                      cursor c return dept%rowtype is select * from dept;
                procedure proc is
END PKG;

CREATE OR REPLACE PAKCAGE BODY PKG IS
      cursor c return dept%rowtype is select * from dept;
PROCEDURE PROC IS
BEGIN
      for v in c loop
           dbms_output.put_line('Deptno = ' || v.deptno || ' Dname = ' ||
                                                             v.dname || ' Loc = ' || v.loc);
      end loop;
END PROC;
END PKG;
Output:
SQL> exec pkg.proc
        Deptno = 10 Dname = ACCOUNTING Loc = NEW YORK
        Deptno = 20 Dname = RESEARCH Loc = DALLAS
        Deptno = 30 Dname = SALES Loc = CHICAGO
        Deptno = 40 Dname = OPERATIONS Loc = BOSTON

Ex2:
CREATE OR REPLACE PAKCAGE BODY PKG IS
      cursor c return dept%rowtype is select * from dept where deptno > 20;
PROCEDURE PROC IS
BEGIN
      for v in c loop
           dbms_output.put_line('Deptno = ' || v.deptno || ' Dname = ' ||
                                            v.dname || ' Loc = ' || v.loc);
      end loop;
END PROC;
END PKG;
Output:
             SQL> exec pkg.proc
                  Deptno = 30 Dname = SALES Loc = CHICAGO
                  Deptno = 40 Dname = OPERATIONS Loc = BOSTON</em></span>

REF CURSORS AND CURSOR VARIABLES
This is unconstrained cursor which will return different types depends upon the user input.
Ref cursors cannot be closed implicitly.
Ref cursor with return type is called strong cursor.
Ref cursor without return type is called weak cursor.
You can declare ref cursor type in package spec as well as body.
You can declare ref cursor types in local subprograms or anonymous blocks.
Cursor variables can be assigned from one to another.
You can declare a cursor variable in one scope and assign another cursor variable with different scope, then you can use the cursor variable even though the assigned cursor variable goes out of scope.
Cursor variables can be passed as parameters to the subprograms.
Cursor variables modes are in or out or in out.
Cursor variables cannot be declared in package spec and package body (excluding subprograms).
You cannot user remote procedure calls to pass cursor variables from one server to another.
Cursor variables cannot use for update clause.
You can not assign nulls to cursor variables.
You cannot compare cursor variables for equality, inequality and nullity.
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
CREATE OR REPLACE PROCEDURE REF_CURSOR(TABLE_NAME IN VARCHAR) IS
type t is ref cursor;
c t;
v_dept dept%rowtype;
type r is record(ename emp.ename%type,job emp.job%type,sal emp.sal%type);
v_emp r;
v_stud student.name%type;
BEGIN
if table_name = 'DEPT' then
open c for select * from dept;
elsif table_name = 'EMP' then
open c for select ename,job,sal from emp;
elsif table_name = 'STUDENT' then
open c for select name from student;
end if;
loop
if table_name = 'DEPT' then
fetch c into v_dept;
exit when c%notfound;
dbms_output.put_line('Deptno = ' || v_dept.deptno || ' Dname = ' ||
v_dept.dname || ' Loc = ' || v_dept.loc);
elsif table_name = 'EMP' then
fetch c into v_emp;
exit when c%notfound;
dbms_output.put_line('Ename = ' || v_emp.ename || ' Job = ' || v_emp.job
|| ' Sal = ' || v_emp.sal);
elsif table_name = 'STUDENT' then
fetch c into v_stud;
exit when c%notfound;
dbms_output.put_line('Name = ' || v_stud);
end if;
end loop;
close c;
END;

Output:
SQL> exec ref_cursor('DEPT')

Deptno = 10 Dname = ACCOUNTING Loc = NEW YORK
Deptno = 20 Dname = RESEARCH Loc = DALLAS
Deptno = 30 Dname = SALES Loc = CHICAGO
Deptno = 40 Dname = OPERATIONS Loc = BOSTON

SQL> exec ref_cursor('EMP')

Ename = SMITH Job = CLERK Sal = 800
Ename = ALLEN Job = SALESMAN Sal = 1600
Ename = WARD Job = SALESMAN Sal = 1250
Ename = JONES Job = MANAGER Sal = 2975
Ename = MARTIN Job = SALESMAN Sal = 1250
Ename = BLAKE Job = MANAGER Sal = 2850
Ename = CLARK Job = MANAGER Sal = 2450
Ename = SCOTT Job = ANALYST Sal = 3000
Ename = KING Job = PRESIDENT Sal = 5000
Ename = TURNER Job = SALESMAN Sal = 1500
Ename = ADAMS Job = CLERK Sal = 1100
Ename = JAMES Job = CLERK Sal = 950
Ename = FORD Job = ANALYST Sal = 3000
Ename = MILLER Job = CLERK Sal = 1300

SQL> exec ref_cursor('STUDENT')

Name = saketh
Name = srinu
Name = satish
Name = sudha

CURSOR EXPRESSIONS
You can use cursor expressions in explicit cursors.
You can use cursor expressions in dynamic SQL.
You can use cursor expressions in REF cursor declarations and variables.
You cannot use cursor expressions in implicit cursors.
Oracle opens the nested cursor defined by a cursor expression implicitly as soon as it fetches the data containing the cursor expression from the parent or outer cursor.
Nested cursor closes if you close explicitly.
Nested cursor closes whenever the outer or parent cursor is executed again or closed or canceled.
Nested cursor closes whenever an exception is raised while fetching data from a parent cursor.
Cursor expressions cannot be used when declaring a view.
Cursor expressions can be used as an argument to table function.
You cannot perform bind and execute operations on cursor expressions when using the cursor expressions in dynamic SQL.
USING NESTED CURSORS OR CURSOR EXPRESSIONS
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<span style="color: #3366ff;"><em>Ex:
DECLARE
cursor c is select ename,cursor(select dname from dept d where e.empno = d.deptno)  from emp e;
type t is ref cursor;
c1 t;
c2 t;
v1 emp.ename%type;
v2 dept.dname%type;
BEGIN
open c;
loop
     fetch c1 into v1;
          exit when c1%notfound;
          fetch c2 into v2;
          exit when c2%notfound;
          dbms_output.put_line('Ename = ' || v1 || ' Dname = ' || v2);
end loop;
end loop;
close c;
END;</em></span>
 CURSOR CLAUSES
Return
For update
Where current of
Bulk collect
RETURN
Cursor c return dept%rowtype is select *from dept;
Or
Cursor c1 is select *from dept;
Cursor c return c1%rowtype is select *from dept;
Or
Type t is record(deptno dept.deptno%type, dname dept.dname%type);
Cursor c return t is select deptno, dname from dept;
FOR UPDATE AND WHERE CURRENT OF
Normally, a select operation will not take any locks on the rows being accessed. This will allow other sessions connected to the database to change the data being selected. The result set is still consistent. At open time, when the active set is determined, oracle takes a snapshot of the table. Any changes that have been committed prior to this point are reflected in the active set. Any changes made after this point, even if they are committed, are not reflected unless the cursor is reopened, which will evaluate the active set again.
However, if the FOR UPDATE caluse is pesent, exclusive row locks are taken on the rows in the active set before the open returns. These locks prevent other sessions from changing the rows in the active set until the transaction is committed or rolled back. If another session already has locks on the rows in the active set, then SELECT … FOR UPDATE operation will wait for these locks to be released by the other session. There is no time-out for this waiting period. The SELECT…FOR UPDATE will hang until the other session releases the lock. To handle this situation, the NOWAIT clause is available.
Syntax:
Select …from … for update of column_name [wait n];
If the cursor is declared with the FOR UPDATE clause, the WHERE CURRENT OF clause can be used in an update or delete statement.
Syntax:
Where current of cursor;
PgSQL
1
2
3
4
5
6
7
8
9
<span style="color: #3366ff;"><em>Ex:
DECLARE
       cursor c is select * from dept for update of dname;
BEGIN
       for v in c loop
             update dept set dname = 'aa' where current of c;
             commit;
       end loop;
END;</em></span>

BULK COLLECT
This is used for array fetches
With this you can retrieve multiple rows of data with a single roundtrip.
This reduces the number of context switches between the pl/sql and sql engines.
Reduces the overhead of retrieving data.
You can use bulk collect in both dynamic and static sql.
You can use bulk collect in select, fetch into and returning into clauses.
SQL engine automatically initializes and extends the collections you reference in the bulk collect clause.
Bulk collect operation empties the collection referenced in the into clause before executing the query.
You can use the limit clause of bulk collect to restrict the no of rows retrieved.
You can fetch into multible collections with one column each.
Using the returning clause we can return data to the another collection.
BULK COLLECT IN FETCH
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<span style="color: #3366ff;"><em>Ex:
DECLARE
     Type t is table of dept%rowtype;
     nt t;
     Cursor c is select *from dept;
BEGIN
     Open c;
     Fetch c bulk collect into nt;
     Close c;
     For i in nt.first..nt.last loop
           dbms_output.put_line('Dname = ' || nt(i).dname || ' Loc = ' ||
                                                          nt(i).loc);
     end loop;
END;</em></span>
Output:
Dname = ACCOUNTING Loc = NEW YORK
Dname = RESEARCH Loc = DALLAS
Dname = SALES Loc = CHICAGO
Dname = OPERATIONS Loc = BOSTON

BULK COLLECT IN SELECT
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<span style="color: #3366ff;"><em>Ex:
DECLARE
     Type t is table of dept%rowtype;
     Nt t;
BEGIN
     Select * bulk collect into nt from dept;
     for i in nt.first..nt.last loop
           dbms_output.put_line('Dname = ' || nt(i).dname || ' Loc = ' ||
                                                                nt(i).loc);
     end loop;
END;</em></span>
Output:
Dname = ACCOUNTING Loc = NEW YORK
Dname = RESEARCH Loc = DALLAS
Dname = SALES Loc = CHICAGO
Dname = OPERATIONS Loc = BOSTON

LIMIT IN BULK COLLECT
You can use this to limit the number of rows to be fetched.
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<span style="color: #3366ff;"><em>Ex:
DECLARE
     Type t is table of dept%rowtype;
     nt t;
     Cursor c is select *from dept;
BEGIN
     Open c;
     Fetch c bulk collect into nt limit 2;
     Close c;
     For i in nt.first..nt.last loop
           dbms_output.put_line('Dname = ' || nt(i).dname || ' Loc = ' || nt(i).loc);
     end loop;
END;</em></span>
Output:
Dname = ACCOUNTING Loc = NEW YORK
Dname = RESEARCH Loc = DALLAS
 MULTIPLE FETCHES IN INTO CLAUSE
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<span style="color: #3366ff;"><em>Ex1:
     DECLARE
           Type t is table of dept.dname%type;
           nt t;
           Type t1 is table of dept.loc%type;
           nt1 t;
           Cursor c is select dname,loc from dept;
      BEGIN
           Open c;
           Fetch c bulk collect into nt,nt1;
           Close c;
           For i in nt.first..nt.last loop
                  dbms_output.put_line('Dname = ' || nt(i));
           end loop;
           For i in nt1.first..nt1.last loop
                  dbms_output.put_line('Loc = ' || nt1(i));
           end loop;
      END;</em></span>
Output:
Dname = ACCOUNTING
Dname = RESEARCH
Dname = SALES
Dname = OPERATIONS
Loc = NEW YORK
Loc = DALLAS
Loc = CHICAGO
Loc = BOSTON

<span style="color: #3366ff;"><em>Ex2:
DECLARE
      type t is table of dept.dname%type;
      type t1 is table of dept.loc%type;
      nt t;
      nt1 t1;
BEGIN
      Select dname,loc bulk collect into nt,nt1 from dept;
      for i in nt.first..nt.last loop
           dbms_output.put_line('Dname = ' || nt(i));
      end loop;
      for i in nt1.first..nt1.last loop
           dbms_output.put_line('Loc = ' || nt1(i));
      end loop;
END;</em></span>
Output:
Dname = ACCOUNTING
Dname = RESEARCH
Dname = SALES
Dname = OPERATIONS
Loc = NEW YORK
Loc = DALLAS
Loc = CHICAGO
Loc = BOSTON
 RETURNING CLAUSE IN BULK COLLECT
You can use this to return the processed data to the ouput variables or typed variables.
PgSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<span style="color: #3366ff;"><em>Ex:
DECLARE
       type t is table of number(2);
       nt t := t(1,2,3,4);
       type t1 is table of varchar(2);
       nt1 t1;
       type t2 is table of student%rowtype;
       nt2 t2;
BEGIN
       select name bulk collect into nt1 from student;
       forall v in nt1.first..nt1.last
                   update student set no = nt(v) where name = nt1(v) returning  
                              no,name,marks bulk collect into nt2;
       for v in nt2.first..nt2.last loop
               dbms_output.put_line('Marks = ' || nt2(v));
       end loop;
END;</em></span>
Output:
Marks = 100
Marks = 200
Marks = 300
Marks = 400
POINTS TO REMEMBER
Cursor name can be up to 30 characters in length.
Cursors declared in anonymous blocks or subprograms closes automatically when that block terminates execution.
%bulk_rowcount and %bulk_exceptions can be used only with forall construct.
Cursor declarations may have expressions with column aliases.
These expressions are called virtual columns or calculated columns.

- See more at: http://alloracleapps.com/oracle/cursors-and-bulk-collect/#sthash.P3XKFEKv.dpuf