Tuesday, October 21, 2014

Handling Exception


Error Handling in oracle

ERROR
    Any departure from the expected behavior of the system or program,
    which stops the working of the system is an error.

    Types : compile time error
        Run time error
EXCEPTION
    Any error or problem which one can handle and continue to work normally.

Handling Exception


    When exception is raised, control passes to the exception section of the block.

    i.e. EXCEPTION
        WHEN name_of_exception THEN

    Types : Pre Defined Exceptions
        User Defined Exceptions


Predefined Exception
*********************

    Oracle has predefined several exceptions that correspond to the most common oracle errors.

    ------------------------------------------------------------------------   
    Exception            Oracle Error         SQL Code Value
    ------------------------------------------------------------------------           
    ZERO_DIVIDE            ORA-01476        -1476
    NO_DATA_FOUND          ORA-01403        +100
    DUP_VAL_ON_INDEX       ORA-00001        -1
    TOO_MANY_ROWS          ORA-01422        -1422
    VALUE_ERROR            ORA-06502        -6502
    CURSOR_ALREADY_OPEN    ORA-06511        -6511
    OTHERS
   ------------------------------------------------------------------------


-->-- ZERO_DIVIDE  --<--

    Your program attempts to divide a number by zero.

    DECLARE
      v_result NUMBER;
    BEGIN
      SELECT 23 / 0 INTO v_result FROM dual;
    EXCEPTION
      WHEN ZERO_DIVIDE THEN
        dbms_output.put_line('Divisor is equal to zero');
    END;
   

-->-- NO_DATA_FOUND --<--

    Single row SELECT returned no rows or your program referenced a deleted element in a nested table
    or an uninitialized element in an associative array (index-by table).


    CREATE TABLE test_tb(id NUMBER PRIMARY KEY);

    DECLARE
      v_id NUMBER;
    BEGIN
      SELECT id INTO v_id FROM test_tb;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        dbms_output.put_line('There is no data inside the table');
    END;


-->-- DUP_VAL_ON_INDEX --<--


    A program attempted to insert duplicate values in a column that is constrained by a unique index.

    INSERT INTO test_tb VALUES (1);
    INSERT INTO test_tb VALUES (2);
    commit;

    BEGIN
      INSERT INTO test_tb VALUES (2);
    EXCEPTION
      WHEN DUP_VAL_ON_INDEX THEN
        dbms_output.put_line('Duplicate values are not allowed');
    END;



-->-- TOO_MANY_ROWS --<--

    Single row SELECT returned multiple rows.

    DECLARE
      v_id NUMBER;
    BEGIN
      SELECT id INTO v_id FROM test_tb;
    EXCEPTION
      WHEN TOO_MANY_ROWS THEN
        dbms_output.put_line('Query returning more than one row');
    END;

    DROP TABLE test_tb;


-->-- VALUE_ERROR --<--

    An arithmetic, conversion, truncation, or size constraint error occurred.

    DECLARE
      num1 NUMBER(2);
    BEGIN
      num1 := 345;
    EXCEPTION
      WHEN VALUE_ERROR THEN
        dbms_output.put_line('check the size of the variable');
    END;


-->-- CURSOR_ALREADY_OPEN --<--

    A program attempted to open an already opened cursor.


    CREATE TABLE emp(id NUMBER, name VARCHAR2(30));

    BEGIN
       INSERT INTO emp VALUES(1,'Name1');
       INSERT INTO emp VALUES(2,'Name2');
       INSERT INTO emp VALUES(3,'Name3');
       INSERT INTO emp VALUES(4,'Name4');
       COMMIT;
    END;
   

    SELECT * FROM emp;

    DECLARE
      cursor emp_c IS
        SELECT * FROM emp;
      all_data emp%ROWTYPE;
    BEGIN
      OPEN emp_c;
      OPEN emp_c;
      NULL;
      CLOSE emp_c;
    EXCEPTION
      WHEN CURSOR_ALREADY_OPEN THEN
        dbms_output.put_line('Cursor already opened');
    END;

    DROP TABLE emp;


-->-- OTHERS --<--

        DECLARE
        v_result NUMBER;
      BEGIN
        SELECT 23 / 0 INTO v_result FROM dual;
      EXCEPTION
        WHEN CURSOR_ALREADY_OPEN THEN
          dbms_output.put_line('Cursor already opened');
        WHEN OTHERS THEN
          dbms_output.put_line('Some other error ' || SQLERRM);
      END;


User Defined Exception

**********************


    A user-defined exception is an error that is defined by the programmer.
    User-defined exceptions are declared in the declarative section of a PL/SQL block. Just like variables,
    exceptions have a type EXCEPTION and scope.


    DECLARE
      v_gender CHAR := '&gender';
      gender_ex EXCEPTION;
    BEGIN
      IF v_gender NOT IN ('M', 'F', 'm', 'f') THEN
        RAISE gender_ex;
      END IF;
      dbms_output.put_line('Gender : '||v_gender);
    EXCEPTION
      WHEN gender_ex THEN
        dbms_output.put_line('Please Enter valid gender');
    END;


    create table test_insert (id NUMBER, Name VARCHAR2(30));

    DECLARE
           abort_ex EXCEPTION;
    BEGIN
         FOR i IN 1..100
         LOOP
            BEGIN
                IF mod(i,10)=0 THEN
                   RAISE abort_ex;
                END IF;
            INSERT INTO test_insert VALUES(i, 'Name'||i);
            EXCEPTION
                    WHEN abort_ex THEN
                    NULL;
             END;
              END LOOP;
             COMMIT;
    END;

    SELECT * FROM test_insert;
 
    DROP TABLE test_insert;


SQLERRM and SQLCODE
********************

    SQLCODE returns the current error code, and SQLERRM returns the current error message text;
    For user-defined exception SQLCODE returns 1 and SQLERRM returns “user-defined exception”.
    SQLERRM will take only negative value except 100. If any positive value other than 100 returns non-oracle exception.


    CREATE TABLE test_tb (id NUMBER);

    DECLARE
      v_id NUMBER;
    BEGIN
      SELECT id INTO v_id FROM test_tb;
      dbms_output.put_line(v_id);
    EXCEPTION
      WHEN OTHERS THEN
        dbms_output.put_line('SQLERRM   :   ' || SQLERRM);
        dbms_output.put_line('SQLCODE   :   ' || SQLCODE);
    END;

/*sample output*/

    SQLERRM   :   ORA-01403: no data found
    SQLCODE   :   100

    DROP TABLE test_tb;


PRAGMA EXCEPTION_INIT

*********************
 
    Using this you can associate a named exception with a particular oracle error.
    This gives you the ability to trap this error specifically, rather than via an OTHERS handler.

Syntax:

    PRAGMA EXCEPTION_INIT(exception_name, oracle_error_number);

    DECLARE
      v_result NUMBER;
      PRAGMA EXCEPTION_INIT(Invalid, -1476);
    BEGIN
      SELECT 453 / 0 INTO v_result FROM dual;
      dbms_output.put_line('Result : ' || v_result);
    EXCEPTION
      WHEN INVALID THEN
        dbms_output.put_line('Invalid Exception');
    END;



RAISE_APPLICATION_ERROR

************************


    You can use this built-in function to create your own error messages, which can be more descriptive than named exceptions.

Error Number :

    Oracle Error Range :   From -00000 to -19999
      User Error Range  :   From -20000 to -20999


      DECLARE
        v_gender CHAR := '&gender';
    BEGIN
        IF v_gender NOT IN ('M', 'F', 'm', 'f') THEN
          RAISE_APPLICATION_ERROR(-20003, 'Enter valid gender');
        END IF;
        dbms_output.put_line('Gender : ' || v_gender);
    END;


Saturday, October 4, 2014

Package




1. You can groups logical related subprogram (procedures and functions)
2. It consist of two parts
        I) specification
        II) Body
3. It allows the oracle server to read multiple object in to a memory once
4. You can declare global variable,cursor, user define exeption
5. Overloading 
6. we can't create anonyms block inside the package



create table err_log(sno NUMBER, u_name VARCHAR2(30), error_msg CLOB, hap_tm TIMESTAMP);

select * from err_log;


--stand alone procedure

CREATE OR REPLACE PROCEDURE emp_sal_sp(p_employee_id IN employees.employee_id%TYPE) IS
    v_salary     employees.salary%TYPE;
    v_first_name employees.first_name%TYPE;
    v_error      VARCHAR2(1000);
BEGIN
    SELECT salary,
           first_name
      INTO v_salary,
           v_first_name
      FROM employees
     WHERE employee_id = p_employee_id;
    dbms_output.put_line('Salary of ' || v_first_name || ' is ' || v_salary);
EXCEPTION
    WHEN OTHERS THEN
        v_error := 'Error while fetching salary. Error : ' || SQLERRM;
        INSERT INTO err_log
        VALUES
            (1,
             USER,
             v_error,
             systimestamp);
    commit;
END emp_sal_sp;


BEGIN
  -- Call the procedure
  emp_sal_sp(p_employee_id => :p_employee_id);
END;


CREATE OR REPLACE PROCEDURE emp_hdt_sp(p_employee_id IN employees.employee_id%TYPE) IS
    v_hire_date  DATE;
    v_first_name employees.first_name%TYPE;
    v_error      VARCHAR2(1000);
BEGIN
    SELECT hire_date,
           first_name
      INTO v_hire_date,
           v_first_name
      FROM employees
     WHERE employee_id = p_employee_id;
    dbms_output.put_line(v_first_name || ' hired on ' || to_char(v_hire_date,'month ddth, yyyy'));
EXCEPTION
    WHEN OTHERS THEN
        v_error := 'Error while fetching salary. Error : ' || SQLERRM;
        INSERT INTO err_log
        VALUES
            (1,
             USER,
             v_error,
             systimestamp);
    commit;
END emp_hdt_sp;



BEGIN
  -- Call the procedure
  emp_hdt_sp(p_employee_id => :p_employee_id);
END;


create or replace function sum_fn (p_a IN NUMBER, p_b IN NUMBER)
RETURN NUMBER
IS
v_c NUMBER;
BEGIN
v_c := p_a + p_b;
RETURN v_c;
END;
/




--Specification Part

CREATE OR REPLACE PACKAGE emp_pkg 
IS 
PROCEDURE emp_sal_sp(p_employee_id IN employees.employee_id%TYPE);
PROCEDURE emp_hdt_sp(p_employee_id IN employees.employee_id%TYPE);

FUNCTION sum_fn (p_a IN NUMBER, p_b IN NUMBER)
RETURN NUMBER;

END emp_pkg ;

--Body Part

CREATE OR REPLACE PACKAGE BODY emp_pkg 
IS 

PROCEDURE emp_sal_sp(p_employee_id IN employees.employee_id%TYPE) IS
    v_salary     employees.salary%TYPE;
    v_first_name employees.first_name%TYPE;
    v_error      VARCHAR2(1000);
BEGIN
    SELECT salary,
           first_name
      INTO v_salary,
           v_first_name
      FROM employees
     WHERE employee_id = p_employee_id;
    dbms_output.put_line('Salary of ' || v_first_name || ' is ' || v_salary);
EXCEPTION
    WHEN OTHERS THEN
        v_error := 'Error while fetching salary. Error : ' || SQLERRM;
        INSERT INTO err_log
        VALUES
            (1,
             USER,
             v_error,
             systimestamp);
    commit;
END emp_sal_sp;


PROCEDURE emp_hdt_sp(p_employee_id IN employees.employee_id%TYPE) IS
    v_hire_date  DATE;
    v_first_name employees.first_name%TYPE;
    v_error      VARCHAR2(1000);
BEGIN
    SELECT hire_date,
           first_name
      INTO v_hire_date,
           v_first_name
      FROM employees
     WHERE employee_id = p_employee_id;
    dbms_output.put_line(v_first_name || ' hired on ' || to_char(v_hire_date,'month ddth, yyyy'));
EXCEPTION
    WHEN OTHERS THEN
        v_error := 'Error while fetching salary. Error : ' || SQLERRM;
        INSERT INTO err_log
        VALUES
            (1,
             USER,
             v_error,
             systimestamp);
    commit;
END emp_hdt_sp;

FUNCTION sum_fn (p_a IN NUMBER, p_b IN NUMBER)
RETURN NUMBER
IS
v_c NUMBER;
BEGIN
v_c := p_a + p_b;
RETURN v_c;
END;

END emp_pkg;
/


A package specification can exist without a package body, but 
a package body can't exist without a package specification.


--Executing procedure inside the package

BEGIN
 emp_pkg.emp_sal_sp(120);
END;

--Executing function inside the package

SELECT emp_pkg.sum_fn(23,567) FROM dual;

-- You can declare global variable,cursor, user define exeption


create or replace package all_detail
as
PROCEDURE emp2sal (a IN NUMBER);
PROCEDURE emp2exep (a IN NUMBER);
FUNCTION add2num (a IN NUMBER, b IN NUMBER)
RETURN NUMBER;

c NUMBER(8);  --global declaration

        abort_ex EXCEPTION; --global exception declaration
        
CURSOR emp_rec  --global cursor declaration
IS
SELECT first_name, salary, hire_date, department_id
FROM employees;

End all_detail;


create or replace package body all_detail
as

PROCEDURE emp2sal (a IN NUMBER)
AS

BEGIN
  SELECT salary
INTO   c
  FROM   Employees
WHERE  Employee_id = a;
Dbms_output.put_line('Salary of Employee ' || a || ' is ' || c);
EXCEPTION

        WHEN no_data_found THEN
Dbms_output.put_line('Please enter valid id');

END emp2sal;

PROCEDURE emp2exep (a IN NUMBER)
AS

BEGIN
  SELECT Round(Months_between(sysdate,hire_date)/12)
INTO   c
  FROM   Employees
WHERE  Employee_id = a;
Dbms_output.put_line( c || '  Years');
EXCEPTION
        WHEN no_data_found THEN
Dbms_output.put_line('Please enter valid id');
END emp2exep;



FUNCTION add2num (a IN NUMBER, b IN NUMBER)
RETURN NUMBER
AS
BEGIN
c := a+b;
RETURN C;
END;

End all_detail;


/*Declaring a Bodiless Package */


CREATE OR REPLACE PACKAGE global_constant
IS
     mile_2_kilo     CONSTANT  NUMBER :=  1.6093;
     kilo_2_mile     CONSTANT  NUMBER :=  0.6214;
     yard_2_meter    CONSTANT  NUMBER :=  0.9144;
     meter_2_yard    CONSTANT  NUMBER :=  1.0936;
END global_constant;


BEGIN
DBMS_OUTPUT.PUT_LINE('20 miles = ' || 20*global_constant.mile_2_kilo||' km');
END;


/*Forward Declaration in package */

DECLARE
      PROCEDURE P2;   --  forward declaration
      PROCEDURE P3; 
 
 PROCEDURE P1 IS
      BEGIN
         dbms_output.put_line('From procedure p1');
         p2;
      END P1;
      
      PROCEDURE P2 IS
      BEGIN
         dbms_output.put_line('From procedure p2');
         p3;
      END P2;
      
      PROCEDURE P3 IS
      BEGIN
      dbms_output.put_line('From procedure p3');
      END P3;
BEGIN
     p1;
END;


sample output:

From procedure p1
From procedure p2
From procedure p3


Drop package package_name;

Drop package body package_name;

SELECT text FROM user_source u
WHERE u.name = 'EMP_PKG';


Interview Questions:

What is package?
Advantage of package
Is it possible to create package body with out package specification?
what is package overloading?
what is forward declaration in package?
which data dictionary table contain source code of package?
How to declare global variable, exception and cursor?
How to execute procedure and function inside the package?



Thursday, October 2, 2014

%TYPE and %ROWTYPE



--%type is used to fetch the data type of the particular column


create table product_details
(
p_id     NUMBER(3),
p_nm     VARCHAR2(30),
p_qty    NUMBER(8),
order_dt DATE
);


BEGIN
         INSERT INTO product_details VALUES(100,'Name0',400,'23-Mar-13');
         INSERT INTO product_details VALUES(101,'Name1',600,'26-Apr-13');
         INSERT INTO product_details VALUES(102,'Name2',800,'27-Jan-12');
         INSERT INTO product_details VALUES(103,'Name3',300,'23-Jul-11');
         INSERT INTO product_details VALUES(104,'Name4',200,'22-Aug-11');
         INSERT INTO product_details VALUES(105,'Name5',500,'25-Oct-12');
         commit;
END;
/

SELECT * FROM product_details;

------------------------------------
P_ID       P_NM   P_QTY   ORDER_DT
------------------------------------
100  Name0  400  03/23/2013
101  Name1  600  04/26/2013
102  Name2  800  01/27/2012
103  Name3   300  07/23/2011
104  Name4  200  08/22/2011
105  Name5  500   10/25/2012
------------------------------------



DECLARE
    v_name VARCHAR2(4);
BEGIN
    SELECT p_nm
      INTO v_name
      FROM product_details
     WHERE p_id = 100;
    dbms_output.put_line('Product Name  : ' || v_name);
    --error numeric or value error      
END;


DECLARE
    v_name VARCHAR2(5);
BEGIN
    SELECT p_nm
      INTO v_name
      FROM product_details
     WHERE p_id = 100;
    dbms_output.put_line('Product Name  : ' || v_name);
END;
/


ALTER TABLE product_details
MODIFY p_nm VARCHAR2(15); 


INSERT INTO product_details
VALUES
    (106,
     'name6',
     700,
     '26-Dec-12');

commit;


106  name6 700   12/26/2012


DECLARE
      v_name VARCHAR2(5);
BEGIN
      SELECT p_nm INTO v_name
      FROM product_details
      WHERE p_id = 106;
      dbms_output.put_line('Product Name  : ' || v_name);
      --error
END;
/




DECLARE
    v_name product_details.p_nm%TYPE;
BEGIN
    SELECT p_nm
      INTO v_name
      FROM product_details
     WHERE p_id = 106;
    dbms_output.put_line('Product Name  : ' || v_name);
END;
/




DROP TABLE product_details;


DECLARE
    dep_id     departments.department_id%TYPE;
    dep_name   departments.department_name%TYPE;
    dep_man_id departments.manager_id%TYPE;
    dep_loc_id departments.location_id%TYPE;
BEGIN

    SELECT department_id,
           department_name,
           manager_id,
           location_id
      INTO dep_id,
           dep_name,
           dep_man_id,
           dep_loc_id
      FROM departments
     WHERE department_id = 10;

    dbms_output.put_line('Department_id   :    ' || dep_id);
    dbms_output.put_line('Department_name :    ' || dep_name);
    dbms_output.put_line('Manager_id   :    ' || dep_man_id);
    dbms_output.put_line('Location_id  :    ' || dep_loc_id);

END;
/


--%rowtype is used to fetch the data type of all the column
--Insted of using %type if we use %rowtype means we can reduce the no of variables that we declare



DECLARE
    dep_detail departments%ROWTYPE;
BEGIN

    SELECT *
      INTO dep_detail
      FROM departments
     WHERE department_id = 10;

    dbms_output.put_line('Department_id   :  ' || dep_detail.department_id);
    dbms_output.put_line('Department_name :  ' || dep_detail.department_name);
    dbms_output.put_line('Manager_id   :  ' || dep_detail.manager_id);
    dbms_output.put_line('Location_id  :  ' || dep_detail.location_id);

END;
/


DROP TABLE dept_details;

CREATE TABLE dept_details
(
   dept_id           number(3)   ,
   dept_name         varchar2(30),
   dept_manager_name varchar2(30)
);


insert into dept_details values(10,'dept1','manager_name1');
insert into dept_details values(20,'dept2','manager_name2');

SELECT * FROM dept_details;

    -------------------------------------------------------
    |  DEPT_ID   | DEPT_NAME   | DEPT_MANAGER_NAME |
    +------------+-----------------------+-----------------
    |  10  | dept1     | manager_name1     |
    |  20  | dept2     | manager_name2     |    
    ------------+-----------------------+------------------


DECLARE
    all_data dept_details%ROWTYPE;
BEGIN

    all_data.dept_id           := 100;
    all_data.dept_name         := 'Admin';
    all_data.dept_manager_name := 'John';

    UPDATE dept_details
       SET ROW = all_data
     WHERE dept_id = 10;

    dbms_output.put_line(SQL%ROWCOUNT || ' Row(s) get updated');

END;
/


1 Row(s) get updated


select * from dept_details;


      ---------------------------------------------------
    |  DEPT_ID   | DEPT_NAME   | DEPT_MANAGER_NAME|
      ---------------------------------------------------
    |  100 | Admin    | John         |
    |  20 | dept2    | manager_name2    |
      ---------------------------------------------------

Interview Question :

1. What is the use of %TYPE?
2. What is the use of %ROWTYPE?
3. Difference between %TYPE and %ROWTYPE?



Monday, September 29, 2014

BULK Exceptions



/************************************************************************
*   Handling Exceptions in Bulk Operations                              *
*   Documented on 29-SEP-14 04.35.35.980894 PM +05:30                   *
*   Document By : Murugappan Annamalai                                  *
*   Reference : http://www.dba-oracle.com/plsql/t_plsql_exceptions.htm  *
************************************************************************/


CREATE TABLE bulk_tb (ran_num NUMBER NOT NULL);

--inserting data using bulk collect


DECLARE
    TYPE num_data_typ IS TABLE OF bulk_tb.ran_num%TYPE;
    v_dat num_data_typ := num_data_typ();
BEGIN
     FOR i in 1..200
     LOOP
         v_dat.EXTEND;
         v_dat(v_dat.LAST) := i;
     END LOOP;

     FORALL i IN v_dat.FIRST..v_dat.LAST
         INSERT INTO bulk_tb VALUES(v_dat(i)); 
     commit;
END;


SELECT COUNT(*) FROM bulk_tb;

 COUNT(*)
 -------
     200


TRUNCATE TABLE bulk_tb;


sample2.sql  --without exception part



DECLARE
    TYPE num_data_typ IS TABLE OF bulk_tb.ran_num%TYPE;
    v_dat num_data_typ := num_data_typ();
BEGIN
     FOR i in 1..200
     LOOP
         v_dat.EXTEND;
         v_dat(v_dat.LAST) := i;
     END LOOP;

     v_dat(100) := NULL;  
     /* will cause error while inserting data into bulk_tb
        because of not null constraint */
    
     FORALL i IN v_dat.FIRST..v_dat.LAST
         INSERT INTO bulk_tb VALUES(v_dat(i)); 
     commit;
END;


/*
Error Message :
ORA-01400: cannot insert NULL into ("HR"."bulk_tb"."ran_num")
ORA-06512: at line 15
*/


sample2.sql  --with exception part


DECLARE
    TYPE num_data_typ IS TABLE OF bulk_tb.ran_num%TYPE;
    v_dat num_data_typ := num_data_typ();
BEGIN
     FOR i in 1..200
     LOOP
         v_dat.EXTEND;
         v_dat(v_dat.LAST) := i;
     END LOOP;

     v_dat(100) := NULL;  
     /* will cause error while inserting data into bulk_tb
        because of not null constraint */
    
     BEGIN
          FORALL i IN v_dat.FIRST..v_dat.LAST
                   INSERT INTO bulk_tb VALUES(v_dat(i)); 
          COMMIT;
     EXCEPTION
        WHEN OTHERS THEN
          dbms_output.put_line('Error while inserting bulk record '||SQLERRM);
     END;    
        
END;




SELECT COUNT(*) FROM bulk_tb;

 COUNT(*)
 -------
      99


SQL%BULK_EXCEPTIONS(i).ERROR_INDEX

    Holds the iteration (not the subscript) of the original FORALL statement that raised the exception. 
    In sparsely populated collections,
    the exception row must be found by looping through the original collection the correct number of times.

SQL%BULK_EXCEPTIONS(i).ERROR_CODE 


Holds the exceptions error code.

    The total number of exceptions can be returned using the collections COUNT method,
    which returns zero if no exceptions were raised.  The save_exceptions.sql script,
    a modified version of the handled_exception.sql script, demonstrates this functionality.


   
DECLARE
    TYPE num_data_typ IS TABLE OF bulk_tb.ran_num%TYPE;
    v_dat      num_data_typ := num_data_typ();
    v_ex_count NUMBER(4);
    abort_ex   EXCEPTION;
    PRAGMA EXCEPTION_INIT(abort_ex, -24381);
BEGIN
     FOR i in 1..200
     LOOP
         v_dat.EXTEND;
         v_dat(v_dat.LAST) := i;
     END LOOP;

     v_dat(100) := NULL;
     v_dat(150) := NULL;  
     /* will cause error while inserting data into bulk_tb
        because of not null constraint */
    
     EXECUTE IMMEDIATE 'TRUNCATE TABLE bulk_tb';
    
     BEGIN
          FORALL i IN v_dat.FIRST..v_dat.LAST SAVE EXCEPTIONS
                   INSERT INTO bulk_tb VALUES(v_dat(i)); 
          COMMIT;
     EXCEPTION
        WHEN abort_ex THEN
          v_ex_count := SQL%BULK_EXCEPTIONS.COUNT;
          FOR i IN 1..v_ex_count LOOP
             dbms_output.put_line('Error: ' || i ||' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
          ' Message: ' || SQLERRM(SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
          END LOOP;       
     END;           
END;




/*
Sample output:
Error: 1 Array Index: 100 Message:  -1400: non-ORACLE exception
Error: 2 Array Index: 150 Message:  -1400: non-ORACLE exception
*/



SELECT COUNT(*) FROM bulk_tb;

 COUNT(*)
 -------
     198
   
       
SAVE EXCEPTIONS clause being removed, in the above script now traps a different error number. 
The output from this script is listed below.



/*
Sample output:
Error: 1 Array Index: 100 Message:  -1400: non-ORACLE exception
*/



SELECT COUNT(*) FROM bulk_tb;

 COUNT(*)
 -------
      99


SELECT COUNT(*) FROM bulk_tb;

DROP TABLE bulk_tb;
/


Cursor - FOR UPDATE




/************************************************************************
*   FOR UPDATE clause in oracle                                         *
*   Document By : Murugappan Annamalai                                  *
************************************************************************/


create table prod_details(p_id VARCHAR2(30), P_name VARCHAR2(30));


BEGIN
     --Inserting data into prod_details table
     FOR i IN 1..50 LOOP
         INSERT INTO prod_details VALUES(i,'pname'||i);
     END LOOP;
    
     commit;
END;


SELECT * FROM prod_details;


DECLARE

  CURSOR PROD_DTLS_C IS
    SELECT * FROM PROD_DETAILS T1 FOR UPDATE OF P_ID;

  V_PID     PROD_DETAILS.P_ID%TYPE;
  V_PRDNAME PROD_DETAILS.P_NAME%TYPE;

BEGIN
  OPEN PROD_DTLS_C;
    LOOP
      FETCH PROD_DTLS_C INTO V_PID, V_PRDNAME;
 
       IF PROD_DTLS_C%NOTFOUND THEN
                   EXIT;
       ELSE
                   UPDATE PROD_DETAILS P
                      SET P.P_ID = LPAD(P_ID, 10, 0)
         WHERE CURRENT OF PROD_DTLS_C;
       END IF;
 
    END LOOP;
 
  CLOSE PROD_DTLS_C;
  COMMIT;
END;


select * from PROD_DETAILS;

TRUNCATE TABLE prod_details;


BEGIN
     --Inserting data into prod_details table
     FOR i IN 1..50 LOOP
         INSERT INTO prod_details VALUES(i,'pname'||i);
     END LOOP;
    
     commit;
END;




DECLARE

  CURSOR PROD_DTLS_C IS
    SELECT * FROM PROD_DETAILS T1 FOR UPDATE OF P_ID;

  V_PID     PROD_DETAILS.P_ID%TYPE;
  V_PRDNAME PROD_DETAILS.P_NAME%TYPE;
 
BEGIN
  OPEN PROD_DTLS_C;
    LOOP
      FETCH PROD_DTLS_C INTO V_PID, V_PRDNAME;
 
       IF PROD_DTLS_C%NOTFOUND THEN
          EXIT;
       ELSE
                   UPDATE PROD_DETAILS P
                      SET P.P_ID = LPAD(P_ID, 10, 0)
         WHERE CURRENT OF PROD_DTLS_C;
       END IF;
       COMMIT;
    END LOOP;
       
  CLOSE PROD_DTLS_C;
  --COMMIT;
END;


select * from PROD_DETAILS;


Wednesday, May 28, 2014

Escape Sequence in Oracle




Escape special characters when writing SQL queries

--to include single '

SELECT 'Steven's salary is more than 50k INR' AS "SAL_DETAILS" 

FROM Dual;

ORA-01756 : quoted string not properly terminated

 

SELECT 'Steven''s salary is more than 50k INR' AS "SAL_DETAILS" 

FROM   Dual;

SAL_DETAILS
---------------------------------------
Steven's salary is more than 50k INR



--to include double '




SELECT 'You can print double quot ('''') in oracle' "Info"  

FROM Dual;

Info
---------------------------------------
You can print double quot ('') in oracle



SELECT q'[some test ' some test ' some text ']' AS "In 10g" 
FROM dual;

In 10g
------------------------------------
some test ' some test ' some text '




--Escape wild card characters ( _ and % )


           The LIKE keyword allows for string searches.
           The '_' wild card character is used to match exactly one character
           While '%' is used to match zero or more occurrences of any characters.
           These characters can be escaped in SQL as follows.
          
WITH mail_ids AS
   (
     SELECT 'an.murugappan@gmail.com'  mail FROM Dual
     UNION
     SELECT 'an_murugappan@gmail.com'  mail FROM Dual
     UNION
     SELECT 'an%murugappan@gmail.com'  mail FROM Dual
    )
    SELECT * FROM mail_ids
    WHERE mail LIKE '__$_%' ESCAPE '$';


mail
----------------------------------   
an_murugappan@gmail.com

   


WITH mail_ids AS
   (
     SELECT 'an.murugappan@gmail.com'  mail FROM Dual
     UNION
     SELECT 'an_murugappan@gmail.com'  mail FROM Dual
     UNION
     SELECT 'an%murugappan@gmail.com'  mail FROM Dual
    )
    SELECT * FROM mail_ids
    WHERE mail LIKE '__/%%' ESCAPE '/';
   
mail
----------------------------------   
an%murugappan@gmail.com

   
   
Escape ampersand (&) characters in SQL*Plus

SQL> select '&a' FROM dual;

'23'
----
23

SQL> SET ESCAPE '\'
SQL> select '\&a' FROM dual;

'&A'
----
&a

SQL> SET SCAN OFF;
SQL> select '&a' FROM dual;

'&A'
----
&a

SQL> SET SCAN ON;
SQL> select '&a' FROM dual;

'45'
----
45



Data Manipulation Language



Data Manipulation Language (DML) statements are used for managing data within schema objects. Some examples:

    INSERT - insert data into a table
    UPDATE - updates existing data within a table
    DELETE - deletes all records from a table, the space for the records remain
    MERGE  - UPSERT operation (insert or update)



CREATE TABLE prod_details
       (
          prod_id      NUMBER(4)              ,
          prod_name    VARCHAR2(30)           ,
          order_dt     DATE DEFAULT SYSDATE   ,
          Deliver_dt   DATE DEFAULT SYSDATE+3 ,
          comments     VARCHAR2(300)
       );
      

SELECT * FROM prod_details;

no_data_found

        
INSERT

INSERT INTO prod_details(prod_id,prod_name,order_dt,deliver_dt,comments)
       VALUES(100,'Apple iphone 5s','21-May-14','24-May-14','Color : Black');
       
SELECT * FROM prod_details;

---------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
---------------------------------------------------------------------------
100         Apple iphone 5s      5/21/2014      5/24/2014        Color : Black
---------------------------------------------------------------------------

--Inserting records with out mentioning column name

INSERT INTO prod_details
       VALUES(101,'Samsung Galaxy III','20-Aug-14','23-Aug-14','Color : White');

SELECT * FROM prod_details;

---------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
---------------------------------------------------------------------------
100       Apple iphone 5s    5/21/2014  5/24/2014     Color : Black
101      Samsung Galaxy III 8/20/2014   8/23/2014     Color : White
---------------------------------------------------------------------------

--Inserting selective number of values

INSERT INTO prod_details
       VALUES(103,'Moto X','11-May-14','13-May-14');
      
ORA-00947 : not enough values

--While inserting selective number of values mentioning column name is compulsory.

INSERT INTO prod_details (prod_id,prod_name,order_dt,deliver_dt)
       VALUES(103,'Moto X','11-May-14','13-May-14');
      

SELECT * FROM prod_details;

--------------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
--------------------------------------------------------------------------------
100      Apple iphone 5s    5/21/2014   5/24/2014     Color : Black
101      Samsung Galaxy III 8/20/2014   8/23/2014     Color : White
103      Moto X             5/11/2014   5/24/2014
--------------------------------------------------------------------------------

--Inserting NULL value.
--If you want to insert NULL value you can ignore that column at the time of inserting
--or we can use NULL keyword to insert NULL.

INSERT INTO prod_details
       VALUES(104,'Moto G','19-May-14','22-May-14',NULL);
      

SELECT * FROM prod_details;

---------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
---------------------------------------------------------------------------
100      Apple iphone 5s    5/21/2014   5/24/2014     Color : Black
101      Samsung Galaxy III 8/20/2014   8/23/2014     Color : White
103      Moto X             5/11/2014   5/24/2014
104      Noto G             5/19/2014   5/22/2014    
---------------------------------------------------------------------------

--if you are not providing values for order_dt and deliver_dt column default value can be taken.

INSERT INTO prod_details(prod_id,prod_name,comments)
       VALUES(105,'Nokia Lumis 720p','Color : Red');
      
      
SELECT * FROM prod_details;

---------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
----------------------------------------------------------------------------
100      Apple iphone 5s    5/21/2014   5/24/2014     Color : Black
101      Samsung Galaxy III 8/20/2014   8/23/2014     Color : White
103      Moto X             5/11/2014   5/24/2014
104      Moto G             5/19/2014   5/22/2014
105      Nokia Lumis 720p   5/26/2014   5/29/2014     Color : Red
---------------------------------------------------------------------------

--Inserting data by using sub query

CREATE TABLE test_tab (id NUMBER, Name VARCHAR2(30));



INSERT INTO test_tab VALUES(1,'Name1');
INSERT INTO test_tab VALUES(2,'Name2');
INSERT INTO test_tab VALUES(3,'Name3');

SELECT COUNT(*) FROM test_tab;

COUNT(*)
-------
      3

--creating table by using sub query (with out data)

 

CREATE TABLE ins_chk
 
 

SELECT * FROM test_tab
WHERE id = 900;

 

SELECT COUNT(*) FROM ins_chk;

COUNT(*)
-------
      0
           
--Inserting data by using sub query
--copying data from test_tab to ins_chk

 

INSERT INTO ins_chk (SELECT * FROM test_tab);

3 rows inserted in 0.047 seconds.


SELECT COUNT(*) FROM ins_chk;

COUNT(*)
-------
      3
 

    
DROP TABLE test_tab;


DROP TABLE ins_chk;



UPDATE

Syntax :

     UPDATE table_name
        SET column1_name = column1_value,
            column2_name = column2_value,
            column2_name = column3_value,
            columnn_name = columnn_value
      WHERE condition(s);
     

SELECT * FROM prod_details;

---------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
----------------------------------------------------------------------
100      Apple iphone 5s    5/21/2014   5/24/2014     Color : Black
101      Samsung Galaxy III 8/20/2014   8/23/2014     Color : White
103      Moto X             5/11/2014   5/24/2014
104      Moto G             5/19/2014   5/22/2014
105      Nokia Lumis 720p   5/26/2014   5/29/2014     Color : Red
---------------------------------------------------------------------------

UPDATE prod_details ps
   SET ps.prod_name = 'iphone 5s'
 WHERE ps.prod_id = 100;

1 row updated in 0.031 seconds

SELECT *
  FROM prod_details ps
 WHERE ps.prod_id = 100;

--------------------------------------------------------------------
PROD_ID     PROD_NAME      ORDER_DT      DELIVER_DT      COMMENTS
--------------------------------------------------------------------
100         iphone 5s      5/21/2014      5/24/2014    Color : Black
--------------------------------------------------------------------

--update statement with out condition
--If you try to execute update statement without condition it'll update all the records inside the table.

UPDATE prod_details ps
   SET ps.comments = 'None';

5 row updated in 0.031 seconds

SELECT *
  FROM prod_details ps;

---------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
---------------------------------------------------------------------------
100      Apple iphone 5s    5/21/2014   5/24/2014     None
101      Samsung Galaxy III 8/20/2014   8/23/2014     None
103      Moto X             5/11/2014   5/24/2014     None
104      Moto G             5/19/2014   5/22/2014     None
105      Nokia Lumis 720p   5/26/2014   5/29/2014     None
----------------------------------------------------------------------


--if your update text contain ' means you can use following metnod (use '')

UPDATE prod_details ps
SET    ps.comments = 'Some product''s are not available'
WHERE  ps.prod_id = 100;

1 row updated in 0.031 seconds


SELECT *
  FROM prod_details ps
 WHERE ps.prod_id = 100;

------------------------------------------------------------------------------------
PROD_ID     PROD_NAME      ORDER_DT      DELIVER_DT      COMMENTS
------------------------------------------------------------------------------------
100         iphone 5s      5/21/2014      5/24/2014        Some product's are not available
------------------------------------------------------------------------------------


DELETE

Syntax:

     DELETE FROM table_name
     WHERE condition(s);
    
DELETE FROM prod_details
 WHERE prod_id IN (104, 105);

2 row(S) deleted in 0.032 seconds


SELECT *
  FROM prod_details ps;

---------------------------------------------------------------------------------------
PROD_ID     PROD_NAME            ORDER_DT      DELIVER_DT      COMMENTS
---------------------------------------------------------------------------------------
100      Apple iphone 5s    5/21/2014   5/24/2014     Some product's are not available
101      Samsung Galaxy III 8/20/2014   8/23/2014     None
103      Moto X             5/11/2014   5/24/2014     None
---------------------------------------------------------------------------------------


DELETE FROM prod_details;

3 row(s) deleted in 0.062 seconds.

SELECT * FROM prod_details;

no rows selected.


DROP TABLE prod_details;

MERGE = Insert + Update

      -- will update soon.