Oracle 6pm PLSQL
Oracle 6pm PLSQL
                 SQL:
                  • SQL => Structured Query Language
                  • it is a query language
                  • it is non-procedural language. [no programs]
                  • just we write queries to communicate with ORACLE DB
                 PL/SQL:
                  • PL/SQL => Procedural Language / Structured Query Language
                  • it is a programming language
                  • it is procedural language
                  • In this, we develop the programs to communicate with ORACLE
                    DB.
                 Advantages:
                  • improves the performance.
                  • provides control structures.
                  • provides exception handling.
                  • provides reusability.
                  • provides security.
                          request               instance   db
   INSERT
                          response
UPDATE RAM HD
DELETE
                                      request
      PL/SQL program
       INSERT                             response
       UPDATE
       DELETE
provides security:
only authorized users can call our procedures or
functions or packages.
Types of Blocks:
2 types:
    • Anonymous Block
    • Named Block
   Anonymous Block:
   A block without name is called Anonymous block.
   Named Block:
   A block with name is called Named Block.
   Examples:
   procedures, functions, packages, triggers
DECLARE
BEGIN
    END;
    /
                                              PACKAGE dbms_output
dbms_output.put_line('HELLO')
                                              PROCEDURE put_line(…) AS
                                              BEGIN
                                                --code
                                              END;
HELLO
         put_line():
          • it is a packaged procedure.
          • it is used to print the data on screen.
          • it is defined in dbms_output package.
<package_name>.<procedure_name>(<arguments>);
           Example:
             dbms_output.put_line('HELLO');
           BEGIN
             dbms_output.put_line('HELLO');
           END;
           /
   SQL> @D:\batch6pm\HelloDemo.sql
   Output:
   HELLO
       Note:
       Syntax of compiling PL/SQL program:
         @<path_of_file>
Programming Basics:
  data types
  declare
  assign
  print
  read
  initialize
                                 nChar(n)
                                 nVarchar2(n)
           ORACLE 6PM PLSQL Page 5
                                  nVarchar2(n)
                                  nCLOB
Variable:
 • Variable is an Identifier.
 • Variable is a name of storage location.
 • To hold the data variable is required.
 • A variable can hold only 1 value at a time.
Declaring variable:
  Syntax:
            ORACLE 6PM PLSQL Page 6
  Syntax:
    <variable> <data_type>;
  Example:
    x NUMBER(4);
    y VARCHAR2(10);
    z DATE;
Assigning value:
                                         x              y     z
  Assignment operator :=
                                         25            RAJU   25-DEC-2023
  Syntax:
    <variable> := <value>;
  Example:
    x := 25;
    y := 'RAJU';
    z := to_date('25-DEC-2023');
Printing data:
  Example:
    dbms_output.put_line(x);           --prints 25
    dbms_output.put_line(y);           --prints RAJU
Reading data:
  Example:
    x := &x;
  Output:
  enter value for x: 25
Initializing variable:
if value is given at the time of declaration then it is
called "Initialization".
                                    x
                                              x INT := 25;   --initialization
x INT; --declare                null
                                25
                                                        x
x := 25; --assign
                                                        25
        DECLARE           x INT;
        ASSIGN            x := 30;
        PRINT             dbms_output.put_line(x);
        READ              x := &x;
        INITIALIZE x INT := 30;
30 20
30+20 = 50
Program:
 DECLARE                                 x             y               z
   x NUMBER(4);
   y NUMBER(4);                          30           20             50
   z NUMBER(4);
 BEGIN
   dbms_output.put_line('sum=' || z);
 END;
 /
  DECLARE                                   x        y    z
    x NUMBER(4);
    y NUMBER(4);                        5        4        9
    z NUMBER(4);
  BEGIN
    x := &x;
    y := &y;
z := x+y;
    dbms_output.put_line('sum=' || z);
  END;
  /
  SQL> @d:\batch6pm\ReadDemo.sql
  Output:
  Enter value for x: 5
  old 6:     x := &x;
  new 6:       x := 5;
  Enter value for y: 4
  old 7:     y := &y;
  new 7:       y := 4;
  sum=9
  SQL> @d:\batch6pm\ReadDemo.sql
  Output:
  Enter value for x: 5
              ORACLE 6PM PLSQL Page 9
   Enter value for x: 5
   Enter value for y: 4
   sum=9
Syntax:
    Output:
    enter .. empno: 7900
    JAMES 950
   Problem-1:
   mismatch may be there between table column field size
   and variable size.
mismatch
   Problem-2:
   mismatch may be there between table column data type
   and variable data type.
mismatch
%TYPE:
 it is attribute related data type.
            ORACLE 6PM PLSQL Page 11
• it is attribute related data type.
 Syntax:
   <variable> <table_name>.<column_name>%TYPE;
 Examples:
   v_empno EMP.EMPNO%TYPE;
v_ename EMP.ENAME%TYPE;
v_sal EMP.SAL%TYPE;
Example on %type:
DECLARE
  v_empno EMP.EMPNO%TYPE;
  v_ename EMP.ENAME%TYPE;
  v_sal EMP.SAL%TYPE;
BEGIN
  v_empno := &empno;
END;
            ORACLE 6PM PLSQL Page 12
END;
/
Example:
Program to display accout balance of given acno:
ACCOUNTS
ACNO NAME BALANCE
1234 A          80000
1235 B          50000
Program:
DECLARE
  v_acno ACCOUNTS.ACNO%TYPE;
  v_balance ACCOUNTS.BALANCE%TYPE;
BEGIN
  v_acno := &acno;
  dbms_output.put_line('balance=' || v_balance);
END;
/
Output:
Enter value for acno: 1234
balance=80000
v_exp := TRUNC((sysdate-v_hiredate)/365);
Output:
enter … empno: 7499
experience=43 years
%ROWTYPE:
• It is attribute related data type.
• It is used to hold entire row of a table.
• This data type variable can hold 1 row at a time.
• It decreases number of variables.
  Syntax:
    <variable> <table_name>%rowtype;
  Example:
    r1 EMP%ROWTYPE;
r1
r1.ename r1.sal
r1.job
r2 DEPT%ROWTYPE;
r2
                           r2.dname
                                                  r2.loc
                                  v_empno
DECLARE
  v_empno EMP.EMPNO%TYPE;         7499
                                                   r
  r EMP%ROWTYPE;
BEGIN
                          empno ename job mgr hiredate sal comm deptno
  v_empno := &empno;
                          7499 ALLEN .. ..    ..       1600 ..  ..
COMMIT;
  dbms_output.put_line('sal increased..');
END;
/
  DECLARE
    v_empno EMP.EMPNO%TYPE;
  BEGIN
    v_empno := &empno;
COMMIT;
    dbms_output.put_line('record deleted..');
  END;
  /
STUDENT
SID SNAME M1
  DECLARE
    r STUDENT%ROWTYPE;
  BEGIN
    r.sid := &sid;
    r.sname := '&sname';
    r.m1 := &m1;
    dbms_output.put_line('record inserted..');
  END;
  /
(or)
  BEGIN
    INSERT INTO student VALUES(&sid, '&sname', &m1);
    COMMIT;
    dbms_output.put_line('record inserted..');
  END;
  /
                Control Structures:
                 • Control Structure is used to control the flow of
                   execution of program.
                 • To change sequential execution and to transfer the
                   control to our desired location we use Control
                   Structures.
            Conditional IF .. THEN
                        IF .. THEN .. ELSE
                        IF .. THEN .. ELSIF
                        NESTED IF
                        CASE
            Looping                   WHILE
                                      FOR
                                      SIMPLE LOOP
            Jumping                   GOTO
                                      EXIT
                                      EXIT WHEN
                                      CONTINUE
                                      RETURN
IF .. THEN:
Syntax:
IF <condition> THEN
     IF <condition> THEN
         --Statements                   condition -> TRUE
     END IF;
Example:
DECLARE
                                          v_empno     v_hiredate v_exp
  v_empno EMP.EMPNO%TYPE;
  v_hiredate DATE;                         7782         ….        43
  v_exp INT;
BEGIN
  v_empno := &empno;
   v_exp := TRUNC((sysdate-v_hiredate)/365);
   dbms_output.put_line('experience=' || v_exp);
  IF v_exp>42 THEN
     DELETE FROM emp WHERE empno=v_empno;
     COMMIT;
     dbms_output.put_line('record deleted..');
  END IF;
END;
/
Output:
enter .. empno: 7782
experience=43
record deleted..
IF .. THEN .. ELSE:
Syntax:
     IF <condition> THEN
        --Statements                    condition => TRUE
     ELSE
        --Statements                    condition => FALSE
     END IF;
             ORACLE 6PM PLSQL Page 19
    --Statements                    condition => TRUE
  ELSE
    --Statements                    condition => FALSE
  END IF;
Example:
Program to increase salary of given empno based on
job as following:
if job is MANAGER then increase 20% on sal
for others, increase 10% on sal
DECLARE
  v_empno EMP.EMPNO%TYPE;
  v_job EMP.JOB%TYPE;
  v_per FLOAT;
BEGIN
  v_empno := &empno;  --7499
  IF v_job='MANAGER' THEN
     v_per := 20;
  ELSE
     v_per := 10;
  END IF;
COMMIT;
  dbms_output.put_line('job=' || v_job);
  dbms_output.put_line(v_per || '% on sal increased..');
END;
/
Output-1:
Enter value for empno: 7698
job=MANAGER
20% on sal increased..
Output-2:
Enter value for empno: 7499
Example:
      DECLARE
        v_empno EMP.EMPNO%TYPE;
        v_amount FLOAT;
        v_sal EMP.SAL%TYPE;
      BEGIN
        v_empno := &empno;
        v_amount := &amount;
        IF v_sal>10000 THEN
           ROLLBACK;
           dbms_output.put_line('rolled back');
        ELSE
           COMMIT;
           dbms_output.put_line('committed..');
        END IF;
      END;
      /
   Assignment:
   Program to increase salary of given empno based on deptno
   as following:
   if emp is working in deptno 10 then increase 15% on sal
   for others, increase 10% in sal
IF .. THEN .. ELSIF:
  Syntax:
              ORACLE 6PM PLSQL Page 21
Syntax:
   IF <condition1> THEN
      --Statements                     conditon1 => T
   ELSIF <condition2> THEN
      --Statements                     c1 => F, c2 => T
   ELSIF <condition3> THEN
      --Statements                     c1,c2 => F, c3 => T
   .
   .
   ELSE
      --Statements                      c1,c2,c3, … => F
   END IF;
DECLARE
  v_empno EMP.EMPNO%TYPE;
  v_job EMP.JOB%TYPE;
  v_per FLOAT;
BEGIN
  v_empno := &empno;
  IF v_job='MANAGER' THEN
     v_per := 20;
  ELSIF v_job='CLERK' THEN
     v_per := 10;
  ELSE
     v_per := 5;
  END IF;
COMMIT;
  dbms_output.put_line('job=' || v_job);
  dbms_output.put_line(v_per || '% on sal increased..');
END;
/
Assignment:
CASE:
   Simple CASE:
   it can check equality condition only
   Searched CASE:
   it can check any condition
Syntax:
         CASE <expression>
         WHEN <constant1> THEN
           --Statements
         WHEN <constant2> THEN
           --Statements
         .
         .
         ELSE
           --Statements
         END CASE;
      DECLARE
        n INT;
      BEGIN
        n := &n;
        CASE MOD(n,2)
          WHEN 0 THEN
            dbms_output.put_line('EVEN');
          WHEN 1 THEN
            dbms_output.put_line('ODD');
        END CASE;
      END;
      /
Searched CASE:
Syntax:
      CASE
      WHEN <condition1> THEN
        --Statements
      WHEN <condition2> THEN
        --Statements
      .
      .
      ELSE
        --Statements
      END CASE;
Example:
      DECLARE
        n INT;
      BEGIN
        n := &n;
        CASE
        WHEN n>0 THEN
          dbms_output.put_line('+VE');
        WHEN n<0 THEN
          dbms_output.put_line('-VE');
        ELSE
          dbms_output.put_line('ZERO');
        END CASE;
      END;
      /
Assignment:
NESTED IF:
Writing IF in another IF is called "Nested If".
Syntax:
     IF <condition1> THEN
        IF <condition2> THEN
           --Statements               condition1, conditon2 => TRUE
        END IF;
     END IF;
  STUDENT                              RESULT
  SID   SNAME M1 M2 M3                 SID TOTAL AVRG RESULT
  1001 A         70 60 80
  1002 B         55 30 64
Program:
                                                                v_sid
DECLARE
                                                                1001
  v_sid STUDENT.SID%TYPE;
  r1 STUDENT%ROWTYPE;
  r2 RESULT%ROWTYPE;
BEGIN                                                                      r1
  v_sid := &sid; --1001
                                                                SID     SNAME M1 M2 M3
  SELECT * INTO r1 FROM student WHERE sid=v_sid;                1001 A          70 60 80
WHILE:
Syntax:
         WHILE <condition>
         LOOP
           --Statements
         END LOOP;
Example:
 i                        DECLARE                       1 2 3 4 5
                            i INT;
 1
                          BEGIN
 2
                            i := 1;                         i<=4
 3
 4                                                          --------
                               WHILE i<=4                   1<=4       T   1
                               LOOP                         2<=4       T   2
                                 dbms_output.put_line(i);   3<=4       T   3
                                 i := i+1;                  4<=4       T   4
                               END LOOP;                    5<=4       F
                          END;
                          /
Simple Loop:
Syntax:
       LOOP
         --Statements
         EXIT WHEN <condition>;               / EXIT;
       END LOOP;
Example:
         DECLARE
           i INT;
       LOOP
          dbms_output.put_line(i);
          EXIT WHEN i=4;
          i := i+1;
       END LOOP;
     END;
     /
                                         IF i=4 THEN
     EXIT WHEN i=4;
                                            EXIT;
                                         END IF;
EXIT WHEN:
 • it is a jumping control structure.
 • it is used to terminate the loop in the middle of execution.
 • it can be used in LOOP only.
  Syntax:
    EXIT WHEN <condition>;
EXIT:
 • it is a jumping control structure.
 • it is used to terminate the loop in the middle of execution.
 • it can be used in LOOP only.
  Syntax:
    EXIT;
BEGIN
  dbms_output.put_line('HI');
  EXIT;
  dbms_output.put_line('BYE');
END;
/
Output:
ERROR: EXIT must appear inside of loop
Syntax:
Example:
 i                      BEGIN
                          FOR i IN 1 .. 4
 1
                          LOOP
 2
                             dbms_output.put_line(i);
 3
                          END LOOP;
 4
                        END;
                        /
 Note:
  • we have no need to declare for loop variable.
    implicitly it will be declared as NUMBER type.
         BEGIN
           FOR i IN 1 .. 10
           LOOP
              i:=5;
              dbms_output.put_line(i);
           END LOOP;
         END;
         /
         Output:
         ERROR: i cannot be used as assignment target
      END;
      /
      Output:
      ERROR: i must be declared
BEGIN
  FOR i IN REVERSE 1 .. 4
  LOOP
     dbms_output.put_line(i);
  END LOOP;
END;
/
Note:
Till ORACLE 19c, step value will be always 1
From ORACLE 21C, we can specify step value using BY keyword
  BEGIN
    FOR i IN 2 .. 20 BY 2
    LOOP
       dbms_output.put_line(i);
    END LOOP;
  END;
  /
GOTO:
 • when GOTO statement is executed, execution
   jumps to specified label.
Syntax:
<<label>>
--Statements
GOTO <label_name>;
Example:
  DECLARE
    i INT;
  BEGIN
    i := 1;
    <<xyz>>
        dbms_output.put_line(i);
        i:=i+1;
    IF i<=4 THEN
        GOTO xyz;
    END IF;
  END;
  /
Continue:
 • it is used to skip current iteration and continue
   the next iteration.
 • it can be used in LOOP only.
Example:
Program to print numbers from 1 to 10 except 7:
BEGIN
  FOR i IN 1 .. 10
  LOOP
     IF i=7 THEN
        CONTINUE;
     END IF;
     dbms_output.put_line(i);
  END LOOP;
END;
/
                     CURSOR:
                       GOAL:
                       ○ CURSOR is used to hold multiple rows and
                         process them one by one.
INSTANCE DB
DECLARING CURSOR:
   Syntax:
     CURSOR <cursor_name> IS <SELECT QUERY>;
   Example:
     CURSOR c1 IS SELECT ename, sal FROM emp;
OPENING CURSOR:
   Syntax:
     OPEN <cursor_name>;
   Example:
     OPEN c1;
ORACLE
INSTANCE DB
 Syntax:
   FETCH <cursor_name> INTO <variables_list>;
 Example:
   FETCH c1 INTO v_ename, v_sal;
                                                                        v_ename
                                              INSTANCE                    ALLEN
                                              BFR
                             FETCH                                       v_sal
                                              SMITH `800
         c1                  FETCH            ALLEN 1600                 1600
                             FETCH
                                              ..     ..
                             FETCH
CLOSING CURSOR:
   Syntax:
     CLOSE <cursor_name>;
   Example:
     CLOSE c1;
                                          INSTANCE
                                     SMITH 800
  c1
                                     ALLEN 1600
                                     ..      ..
Cursor Attributes:
%FOUND
         Syntax:
           <cursor_name><attribute_name>
         Examples:
           c1%FOUND
           c1%NOTFOUND
           c1%ROWCOUNT
           c1%ISOPEN
 %FOUND:
 • It returns boolean value [true or false].
 • If record is found, it returns TRUE
 • If record is not found, it returns FALSE
 %NOTFOUND:
 • It returns boolean value [true or false].
 • If record is not found, it returns TRUE
 • If record is found, it returns FALSE
 %ROWCOUNT:
 • its default value is 0.
 • if record is found, rowcount value incremented by 1
 %ISOPEN:
 • it returns boolean value.
 • If cursor is opened, it returns TRUE.
 • If cursor is not opened, it returns FALSE.
Examples on CURSOR:
 DECLARE                                                      INSTANCE
   CURSOR c1 IS SELECT ename, sal FROM emp;                    BFR
   v_ename EMP.ENAME%TYPE;                                    SMITH 800
   v_sal EMP.SAL%TYPE;              c1                        ALLEN 1600
 BEGIN                                                        WARD 2000
   OPEN c1;
                                                                v_ename
    LOOP
      FETCH c1 INTO v_ename, v_sal;                               WARD
      EXIT WHEN c1%notfound;
      dbms_output.put_line(v_ename || '    ' || v_sal);         v_sal
    END LOOP;                                                       2000
   CLOSE c1;
 END;
 /
 DECLARE
   CURSOR c1 IS SELECT * FROM emp;
   r EMP%ROWTYPE;
 BEGIN
   OPEN c1;
    LOOP
      FETCH c1 INTO r;
      EXIT WHEN c1%notfound;
      dbms_output.put_line(r.ename || '   ' || r.sal || '   ' || r.hiredate);
    END LOOP;
   CLOSE c1;
 END;
 /
   EMPLOYEE                               HIKE
   EMPNO ENAME SAL                        EMPNO PER
   1001    A              5000            1001   10
   1002    B              3000            1002   20
   1003    C              7000            1003   15
  CLOSE c1;
END;
/
SAL
---------                         0 + 5000 + 10000 + 4000
5000
10000         v_sum:=v_sum+v_sal
                                                                    INSTANCE
4000
                                                                        BFR
                                                                        5000
DECLARE                                                                 10000
  CURSOR c1 IS SELECT sal FROM emp;                                     4000
  v_sal EMP.SAL%TYPE;
                                    c1
  v_sum FLOAT := 0;
BEGIN
  OPEN c1;
                                 v_Sal                              v_sum
  LOOP                           5000                               0
    FETCH c1 INTO v_sal;         10000                              5000
    EXIT WHEN c1%NOTFOUND;       4000                               15000
            ORACLE 6PM PLSQL Page 40
  LOOP                                  5000           0
    FETCH c1 INTO v_sal;                10000          5000
    EXIT WHEN c1%NOTFOUND;              4000           15000
    v_sum := v_sum+v_sal;                              19000
  END LOOP;
Syntax:
 Example:
   FOR r IN c1
   LOOP
     dbms_output.put_line(r.ename);
   END LOOP;
  DECLARE
    CURSOR c1 IS SELECT * FROM emp;
  BEGIN
    FOR r IN c1
    LOOP
       dbms_output.put_line(r.ename || ' ' || r.sal);
    END LOOP;
  END;
  /
Inline Cursor:
If SEELCT QUERY is specified in CURSOR FOR
LOOP then it is called "Inline Cursor".
  Syntax:
    FOR <variable> IN (<SELECT QUERY>)
    LOOP
      --Statements
    END LOOP;
    BEGIN
      FOR r IN (SELECT * FROM emp)
      LOOP
         dbms_output.put_line(r.ename || '   ' || r.sal);
      END LOOP;
    END;
    /
  Syntax:
    CURSOR <cursor_name>(<parameters_list>) IS <SELECT QUERY>;
  DECLARE
    CURSOR c1(n NUMBER) IS SELECT * FROM emp
    WHERE deptno=n;
    r EMP%ROWTYPE;
  BEGIN
    OPEN c1(20);
    LOOP
      FETCH c1 INTO r;
      EXIT WHEN c1%notfound;
      dbms_output.put_line(r.ename || '    ' || r.sal || ' ' || r.deptno);
    END LOOP;
  END;
  /
Ref Cursor:
    Syntax:
      <cursor_name> SYS_REFCURSOR;
    Example:
      c1 SYS_REFCURSOR;
    Syntax:
      OPEN <cursor_name> FOR <SELECT QUERY>;
    Example:
      OPEN c1 FOR SELECT * FROM emp;
      .
      .
      OPEN c1 FOR SELECT * FROM dept;
  DECLARE
    c1 SYS_REFCURSOR;
    r1 EMp%ROWTYPE;
    r2 DEPT%ROWTYPE;
  BEGIN
    OPEN c1 FOR SELECT * FROM emp;
    LOOP
      FETCH c1 INTO r1;
        ORACLE 6PM PLSQL Page 44
        FETCH c1 INTO r1;
        EXIT WHEN c1%notfound;
        dbms_output.put_line(r1.ename || '   ' || r1.sal);
      END LOOP;
CLOSE c1;
      LOOP
        FETCH c1 INTO r2;
        EXIT WHEN c1%notfound;
        dbms_output.put_line(r2.deptno || ' ' || r2.dname);
      END LOOP;
      CLOSE c1;
    END;
    /
• in this, one cursor can be used        • in this, same cursor can be used for
  for one select query only                multiple select queries
• it is static.                          • it is dynamic.
  select query is fixed.                   select query can be changed.
Types of Cursors:
2 Types:
      ○ Implicit Cursor
      ○ Explicit Cursor
          Simple Cursor
          Ref Cursor
  Implicit Cursor:
   • To execute any DRL or DML command implicitly
     ORACLE uses a cursor. it is called "Implicit Cursor".
SQL%FOUND
DECLARE
  v_empno EMP.EMPNO%TYPE;
  v_amount FLOAT;
BEGIN
  v_empno := &empno;
  v_amount := &amount;
  IF sql%notfound THEN
     dbms_output.put_line('employee not existed..');
  ELSE
     COMMIT;
     dbms_output.put_line('sal increased..');
  END IF;
END;
/
4 steps:
DECLARE CURSOR c1 IS SELECT * FROM emp
OPEN         OPEN c1
FETCH        FETCH c1 INTO r
CLOSE        CLOSE c1
Inline Cursor:
 • we specify select query in cursor for loop
Parameterized cursor:
 • a cursor with parameter
OPEN c1(20);
Ref Cursor:
same cursor can be used for multiple select queries
Types of cursors:
2 types:
   implicit cursor
   explicit cursor
     --Simple cursor
     --ref cursor
Exception Handling:
Types of Errors:
                          3 Types:
                           ○ Compile Time Errors
                           ○ Run Time Errors
                           ○ Logical Errors
                          Examples:
                            missing ;
                            missing end if
                            missing end loop
                            missing )
                            missing '
                          Problem:
                          ○ abnormal termination. it leads to wrong results.
                            we may loss the data.
                                    ORACLE 6PM PLSQL Page 49
        we may loss the data.
     Logical Errors:
      ○ These errors occur due to mistake logic.
      ○ it leads to wrong results.
      ○ programmer must develop correct logic.
Example:
          withdraw:
          v_balance := v_balance + v_amount
Exception:
 • Exception means Run Time Error.
 • it is a problem
 • When run time error occurs our program will be
   terminated in the middle of execution. So, abnormal
   termination will occur.
 • Abnormal termination leads to wrong results or invalid
   data.
 • That is why we must handle the runtime errors.
Exception Handling:
 • The way of handling runtime errors is called
   "Exception Handling".
 • For Exception handling we add EXCEPTION block.
    DECLARE
      --declare the variables
    BEGIN
      --executable statements
      EXCEPTION
         WHEN <Exception_name> THEN
           --Handling code
         WHEN <Exception_name> THEN
           --Handling code
         .
         .
          ORACLE 6PM PLSQL Page 50
                  --Handling code
           .
           .
    END;
    /
  DECLARE
    x NUMBER(4);
    y NUMBER(4);
    z NUMBER(4);
  BEGIN
    x := &x;
    y := &y;
z := x/y;
dbms_output.put_line('z=' || z);
    EXCEPTION
       WHEN zero_divide THEN
        dbms_output.put_line('you cannot divide with 0');
       WHEN value_error THEN
        dbms_output.put_line('size is exceeded or wrong input given');
  END;
  /
  Output-1:
  Enter value for x: 20
  Enter value for y: 10
  z=2
  Output-2:
  Enter value for x: 20
  Enter value for y: 0
Output-3:
Enter value for x: 123456
Enter value for y: 2
size is exceeded or wrong input given
Output-4:
Enter value for x: 'RAJU'
Enter value for y: 2
size is exceeded or wrong input given
Types of Exceptions:
   2 Types:
    ○ Built-In Exception
    ○ User-Defined Exception
   Built-In Exception:
   ○ An exception which is already defined by ORACLE
     DEVELOPERS is called "Built-In Exception".
   ○ These will be raised implicitly
     Examples:
       zero_divide
       value_error
       no_data_found
       dup_val_on_index
       too_many_rows
       invalid_cursor
       cursor_already_open
   zero_divide:
    ○ This exception will be raised when we try to divide
      with 0.
value_error:
 ○ when we give wrong input or when size is
   exceeded then value_error will occur.
no_data_found:
 ○ when we retrieve the data if record is not found
   no_data_found exception will be raised.
Example on no_data_found:
   DECLARE
     v_empno EMP.EMPNO%TYPE;
     r EMP%ROWTYPE;
   BEGIN
     v_empno := &empno;
     EXCEPTION
        WHEN no_data_found THEN
         dbms_output.put_line('no emp exited with
         this empno');
   END;
   /
   Output-1:
   Enter value for empno: 7698
   BLAKE 8104
   Output-2:
   Enter value for empno: 9123
   no emp exited with this empno
dup_val_on_index:
when we try to insert duplicate value in Primary Key column then
     ORACLE 6PM PLSQL Page 53
when we try to insert duplicate value in Primary Key column then
dup_val_on_index exception will be raised.
  Example:
    CREATE TABLE student
    (
    sid NUMBER(4) CONSTRAINT con80 PRIMARY KEY,
    sname VARCHAR2(10)
    );
    BEGIN
      INSERT INTO student VALUES(&sid, '&sname');
      COMMIT;
      dbms_output.put_line('record inserted');
      EXCEPTION
         WHEN dup_val_on_index THEN
          dbms_output.put_line('this sid already assigned..');
    END;
    /
too_many_rows:
 • when select query selects multiple rows then
   too_many_rows exception will be raised.
Example on too_man_rows:
  DECLARE
    v_job EMP.JOB%TYPE;
    r EMP%ROWTYPE;
  BEGIN
    v_job := '&job';
    EXCEPTION
      WHEN too_many_rows THEN
     ORACLE 6PM PLSQL Page 54
         WHEN too_many_rows THEN
          dbms_output.put_line('many rows selected..');
  END;
  /
  Output-1:
  Enter value for job: PRESIDENT
  KING PRESIDENT 12000
  Output-2:
  Enter value for job: CLERK
  many rows selected..
Invalid Cursor:
When we try to fetch for the record without opening
cursor then invalid_cursor exception will be raised.
Example on invalid_cursor:
  DECLARE
    CURSOR c1 IS SELECT * FROM emp;
    r EMP%ROWTYPE;
  BEGIN
    LOOP
       FETCH c1 INTO r;
       EXIT WHEN c1%notfound;
       dbms_output.put_line(r.ename || ' ' || r.sal);
    END LOOP;
CLOSE c1;
    EXCEPTION
       WHEN invalid_cursor THEN
        dbms_output.put_line('cursor is not opened..');
  END;
  /
  Output:
  cursor is not opened..
Example on cursor_already_open:
    DECLARE
      CURSOR c1 IS SELECT * FROM emp;
      r EMP%ROWTYPE;
    BEGIN
      OPEN c1;
OPEN c1;
        LOOP
          FETCH c1 INTO r;
          EXIT WHEN c1%notfound;
          dbms_output.put_line(r.ename || '   ' || r.sal);
        END LOOP;
CLOSE c1;
      EXCEPTION
         WHEN cursor_already_open THEN
          dbms_output.put_line('cursor already opened..');
    END;
    /
    Output:
    cursor already opened..
   Others:
    • It can handle any exception.
Example on Others:
   DECLARE
     ORACLE 6PM PLSQL Page 56
 DECLARE
   x NUMBER(4);
   y NUMBER(4);
   z NUMBER(4);
 BEGIN
   x := &x;
   y := &y;
z := x/y;
dbms_output.put_line('z=' || z);
   EXCEPTION
      WHEN others THEN
       dbms_output.put_line('RTE occurred..');
 END;
 /
 Output-1:
 Enter value for x: 20
 Enter value for y: 0
 RTE occurred..
 Output-2:
 Enter value for x: 123456
 Enter value for y: 2
 RTE occurred..
 Output-3:
 Enter value for x: 'RAJU'
 Enter value for y: 2
 RTE occurred..
z := x/y;
dbms_output.put_line('z=' || z);
   EXCEPTION
      WHEN others THEN
       dbms_output.put_line(SQLERRM);
       --dbms_output.put_line(SQLCODE);
       --dbms_output.put_line('RTE occurred..');
 END;
 /
 User-Defined Exception:
  • An exception which is defined by user is called
    "User-Defined Exception".
  • We define it explicitly and we raise it explicitly.
 1 step:                               3 steps:
 HANDLE                                 • DECLARE
                                        • RAISE
                                        • HANDLE
  Syntax:
    <exception_name> EXCEPTION;
  Examples:
    one_divide EXCEPTION;
    xyz EXCEPTION;
    sunday_not_allow EXCEPTION;
    comm_is_null EXCEPTION;
    Syntax:
      RAISE <exception_name>;
    Examples:
      RAISE one_divide;
      RAISE xyz;
    Syntax:
      EXCEPTION
        WHEN <Exception_name> THEN
           --handling code
    Example:
      EXCEPTION
        WHEN one_divide THEN
          dbms_output.put_line('denominator cannot be 1');
  DECLARE
    x NUMBER(4);
    y NUMBER(4);
    z NUMBER(4);
    one_divide EXCEPTION;
  BEGIN
    x := &x;
    y := &y;
    IF y=1 THEN
       RAISE one_divide;
    END IF;
z := x/y;
dbms_output.put_line('z=' || z);
    EXCEPTION
      WHEN zero_divide THEN
        dbms_output.put_line('denominator cannot be 0');
      WHEN one_divide THEN
        dbms_output.put_line('denominator cannot be 1');
  END;
  /
  Output-1:
  Enter value for x: 10
  Enter value for y: 0
  denominator cannot be 0
  Output-2:
  Enter value for x: 10
 DECLARE
   v_empno EMP.EMPNO%TYPE;
   v_amount FLOAT;
   sunday_not_allow EXCEPTION;
 BEGIN
   v_empno := &empno;
   v_amount := &amount;
    IF to_char(sysdate,'DY')='SUN' THEN
       RAISE sunday_not_allow;
    END IF;
COMMIT;
dbms_output.put_line('sal increased..');
   EXCEPTION
      WHEN sunday_not_allow THEN
       dbms_output.put_line('sal cannot be increased on SUNDAY..');
 END;
 /
 Output-1 [mon-sat]:
 Enter value for empno: 7934
 Enter value for amount: 1000
 sal increased..
 Note:
  • we can raise the exception in 2 ways. they are:
  • using RAISE keyword
  • using RAISE_APPLICATION_ERROR() procedure
 RAISE_APPLICATION_ERROR():
  • it is a procedure.
  • it is used to raise the exception with our own error code and error
    message.
  • our own code must be ranges from -20000 to -20999
   Syntax:
     RAISE_APPLICATION_ERROR(<user_defined_error_code>,
     <user_Defined_error_message>);
   Example:
     RAISE_APPLICATION_ERROR(-20050,'you cannot divide with 1')
       Output:
       ORA-20050: you cannot divide with 1
Example on raise_application_error():
 DECLARE
   v_empno EMP.EMPNO%TYPE;
   v_amount FLOAT;
 BEGIN
   v_empno := &empno;
   v_amount := &amount;
   IF to_char(sysdate,'DY')='SUN' THEN
      RAISE_APPLICATION_ERROR(-20050,'you cannot update on sunday..');
   END IF;
     ORACLE 6PM PLSQL Page 62
  END IF;
COMMIT;
dbms_output.put_line('sal increased..');
END;
/
RAISE RAISE_APLLICATION_ERROR()
• it is a keyword • it is a procedure
pragma exception_init():
 -1                                 Error Code
 unique constraint violated Error Message
 dup_val_on_index                   Error name
• some errors have names. some errors does not have names. To
  give name for unnamed exceptions we use pragma exception_init().
  Syntax:
    pragma exception_init(<user_Defined_exception_name>,
    <built-in_error_code>)
  Example:
    check_violate EXCEPTION;
    pragma exception_init(check_violate, -2290);
Program:
  DECLARE
    check_violate EXCEPTION;
    pragma exception_init(check_violate, -2290);
  BEGIN
    INSERT INTO student VALUES(&sid, '&sname', &m1);
  EXCEPTION
     WHEN dup_val_on_index THEN
      dbms_output.put_line('PK does not accept duplicates..');
     WHEN check_violate THEN
      dbms_output.put_line('marks must be b/w 0 to 100');
END;
/
Output-1:
Enter value for sid: 1005
Enter value for sname: E
Enter value for m1: 78
record inserted..
Output-2:
Enter value for sid: 1005
Enter value for sname: F
Enter value for m1: 90
PK does not accept duplicates..
Output-3:
Enter value for sid: 1006
Enter value for sname: G
Enter value for m1: 567
marks must be b/w 0 to 100
                   PROCEDURE:
                    • PROCEDURE is one ORACLE DB Object.
Types of Procedures:
2 Types:
                     • Stored Procedure
                     • Packaged Procedure
                   Stored Procedure:
                    • A procedure which is defined in SCHEMA [user]
                      is called "Stored Procedure".
                              Example:
                                SCHEMA c##batch6pm
                                  PROCEDURE withdraw            => Stored Procedure
                   Packaged Procedure:
                    • A procedure which is defined in PACKAGE
                      is called "Packaged Procedure".
                              Example:
                                SCHEMA c##batch6pm
                                  PACKAGE bank
                                    PROCEDURE withdraw            => Packaged Procedure
SQL> @d:\batch6pm\ProcedureDemo.sql
ORACLE DB
PROCEDURE addition
--compiled code
     Syntax:
       EXEC[UTE] <procedure_name>(<parameters>);
     Example:
     SQL> EXEC addition(5,4);
     Output:
     sum=9
     DECLARE
       a NUMBER(4);
       b NUMBER(4);
       c NUMBER(4);
     BEGIN
       a := &a;
       b := &b;
     Output:
     Enter .. a: 2
     Enter .. b: 3
     sum=5
Note:
TO modify existing procedure's code we use REPLACE.
Parameter:
 • Parameter is a local variable which is declared in procedure header.
  Syntax:
    <parameter_name> [<parameter_mode>] <parameter_data_type>
  Examples:
    x IN NUMBER
    y OUT NUMBER
    z IN OUT NUMBER
Parameter Modes:
 • There are 3 parameter mods. they are:
   ○ IN
   ○ OUT
     IN OUT
IN:
 • It is default one.
 • It captures input.
 • It is used to bring value into procedure from out of procedure.
 • It is read-only parameter.
 • In procedure call, it can be constant or variable.
Example:
 to see errors:
    SQL> SHOW ERRORS
 OUT:
  • it sends output.
  • it is used to send the result out of the procedure.
  • it is read-write parameter.
  • In procedure call, it must be variable only.
 IN OUT:
  • it captures input and sends output.
  • same parameter takes input and sends output.
  • it is read-write parameter.
  • In procedure call, it must be variable only.
  Note:
  Bind variable:
• A variable which is declared at SQL command prompt is called
  "Bind Variable".
            ORACLE 6PM PLSQL Page 70
  "Bind Variable".
• to write data into bind variable we use bind operator : [colon].
• PRINT command is used to print bind variable value
  Example:
    VAR a NUMBER
  DECLARE
    a NUMBER(4);
    b NUMBER(4);
    c NUMBER(4);
  BEGIN
    a := &a;
    b := &b;
addition(a,b,c);
    dbms_output.put_line('sum=' || c);
  END;
  /
Example:
COMMIT;
    dbms_output.put_line('sal increased..');
  END;
  /
  Calling:
  EXEC update_salary(7499, 2000);
  Output:
  sal increased..
Example:
COMMIT;
dbms_output.put_line('sal increased..');
SQL> PRINT s
Example:
 ACCOUNTS
 ACNO NAME BALANCE
 1001 A           70000
 1002 B           50000
COMMIT;
     IF p_amount>v_balance THEN
        raise_application_error(-20050,'Insufficient funds..');
     END IF;
COMMIT;
     dbms_output.put_line('transaction successful..');
   END;
   /
   Output-1:
   SQL> EXEC withdraw(1001,90000);
   Output:
   ERROR at line 1:
   ORA-20050: Insufficient funds..
   Output-2:
   SQL> EXEC withdraw(1001,10000);
   Output:
   transaction successful..
COMMIT;
   dbms_output.put_line('transaction successful..');
END;
/
Calling:
SQL> EXEC deposit(1001,30000);
Output:
transaction successful..
COMMIT;
dbms_output.put_line('transaction successful..');
SQL> print b
         B
----------
    100000
Calling:
EXEC addition(10,20);                  10,20 => Actual Parameters
Formal Parameter:
 • A parameter which is declared in procedure header
Actual Parameter:
 • A parameter in procedure call
Positional mapping:
 • in this, actual parameter will be mapped with formal parameter
   based on position.
Example:
positional mapping
addition(10,20,30)
Named mapping:
Example:
named mapping
addition(z=>10,x=>20,y=>30)
 Mixed mapping:
 • in this, actual parameters will be mapped with formal parameters
   based on positions and names.
Example:
mixed mapping
addition(10,z=>20,y=>30);
        addition(z=>10,20,30)
        ERROR: a positional mapping may not follow named mapping
    Calling:
    SQL> EXEC addition(10,20,30);
    Output:
    sum=60
    x=10
    y=20
    z=30
Pragma Autonomous_Transaction:
case-1:
                                                     PROCEDURE update_salary
        main program:
        begin transaction t1
        UPDATE => 7521, 2000                            UPDATE => 7499, 1000
        update_salary(7499,1000)                        ROLLBACK
        commit
        end transaction t1
                   EMP
                   EMPNO ENAME SAL
                   7499            ALLEN 1600+1000 = 2600 rolled back 1600
                   7521            WARD 2000+2000 = 4000 rolled back 2000
                     EMP
                     EMPNO ENAME SAL
                     7499               ALLEN 1600+1000 = 2600 rolled back 1600
                     7521               WARD 2000+2000 = 4000 committed 4000
            ROLLBACK;
          END;
          /
          BEGIN
            UPDATE emp SET sal=sal+2000 WHERE empno=7521;
update_salary(7499,1000);
            COMMIT;
          END;
          /
          Note:
          procedure actin cancelled
          main action committed
login as c##batch6pm:
login as c##userA:
EXEC c##batch6pm.addition(2,3,4);
Dropping procedure:
  Syntax:
    DROP PROCEDURE <name>;
  Example:
    DROP PROCEDURE deposit;
 user_procedures
 user_source
 user_procedures:
  • it is a system table.
  • it maintains all procedures, functions and packages
    information.
                     FUNCTION:
                      • FUNCTION is a named block of statements that gets
                        executed on calling.
                      • It can be also called as "Sub Program".
Types of Functions:
2 types:
                          • Stored Functions
                          • Packaged Functions
                     Stored Function:
                     A function which is defined in SCHEMA
                           Example:
                             SCHEMA c##batch6pm
                               FUNCTION check_balance           => stored function
                     Packaged Function:
                     A function which is defined in PACKAGE
                           Example:
                             SCHEMA c##batch6pm
                               PACKAGE bank
                                FUNCTION check_balance           => packaged function
  Example:
    opening account => INSERT => PROCEDURE
    withdraw        => UPDATE => PROCEDURE
    deposit         => UPDATE => PROCEDURE
    closing account => DELETE => PROCEDURE
Note:
 • In FUNCTION, always take IN parameters only.
 • Don't take OUT parameters.
  CREATE FUNCTION
          ORACLE 6PM PLSQL Page 83
  CREATE FUNCTION
  product(x NUMBER, y NUMBER) RETURN NUMBER
  AS
    z NUMBER(4);
  BEGIN
    z := x*y;
    RETURN z;
  END;
  /
    DECLARE
      a NUMBER(4);
      b NUMBER(4);
      c NUMBER(4);
    BEGIN
      a := &a;
      b := &b;
c := product(a,b);
      dbms_output.put_line('product=' || c);
    END;
    /
Example:
  Define a function to find experience of an employee:
    CREATE FUNCTION
    experience(p_empno NUMBER) RETURN NUMBER
    AS
          ORACLE 6PM PLSQL Page 84
    AS
      v_hiredate DATE;
    BEGIN
      SELECT hiredate INTO v_hiredate FROM emp
      WHERE empno=p_empno;
      RETURN TRUNC((sysdate-v_hiredate)/365);
    END;
    /
    Calling:
    SQL> SELECT experience(7788) FROM dual;
    Output:
    EXPERIENCE(7788)
    ----------------
                  41
       ACCOUNTS
       ACNO NAME BALANCE
       1001 A                  100000
       1002 B                  50000
   CREATE FUNCTION
   check_balance(p_acno NUMBER) RETURN NUMBER
   AS
     v_balance ACCOUNTS.BALANCE%TYPE;
          ORACLE 6PM PLSQL Page 85
   v_balance ACCOUNTS.BALANCE%TYPE;
 BEGIN
   SELECT balance INTO v_balance FROM accounts
   WHERE acno=p_acno;
   RETURN v_balance;
 END;
 /
 Calling:
 SQL> select check_balance(1002) FROM dual;
 Output:
 CHECK_BALANCE(1002)
 -------------------
               50000
    RETURN c1;
  END;
  /
  Calling:
  SELECT getdept(10) FROM dual;
PROCEDURE FUNCTION
Dropping Function:
  Syntax:
    DROP FUNCTION <name>;
  Example:
    DROP FUNCTION experience;
   user_procedures
   user_source
   user_procedures:
    • it is a system table.
    • it maintains all procedures, functions and packages
      information.
   user_source:
    • it is a system table.
      it maintains all procedures, functions, packages and
          ORACLE 6PM PLSQL Page 88
     • it maintains all procedures, functions, packages and
       triggers information including code.
                   PACKAGE:
                    • PACKAGE is one ORACLE DB Object.
Creating Package:
                   2 steps:
                    • Package Specification
                    • Package Body
Package Specification:
Package Body:
PACKAGE MATH
  PROCEDURE addition
  FUNCTION product
--Package body
<package_name>.<procedure/function_name>(<parameters>)
Calling:
  Calling Packaged procedure:
       ORACLE 6PM PLSQL Page 92
Calling Packaged procedure:
   EXEC math.addition(5,10);
   Output:
   sum=15
Example:
PACKAGE HR
--Package Specification
--Package Body
       RETURN TRUNC((sysdate-v_hiredate)/365);
       ORACLE 6PM PLSQL Page 94
          RETURN TRUNC((sysdate-v_hiredate)/365);
       END experience;
     END;
     /
     Calling:
     EXEC hr.hire(1001,'A');
EXEC hr.fire(1001);
EXEC hr.hike(7499,1000);
Assignment:                                          ACCOUNTS
                                                     ACNO NAME BALANCE
  PACKAGE BANK                                       1234 A     70000
                                                     1235 B     50000
    PROCEDURE          opening_account => insert
    PROCEDURE          closing_account => delete
    PROCEDURE          withdraw        => update
    PROCEDURE          deposit         => update
Advantages of Packages:
•   provides reusability
•   decreases length of code
•   provides security
•   improves understandability
•   better maintenance
Overloading:
Defining multiple functions / procedures with same name and
different signatures is called "Overloading".
    Example:
      PACKAGE OLDEMO
--Package Specification
--Package Body
 Calling:
 SQL> SELECT oldemo.addition(1,2) from dual;
 OLDEMO.ADDITION(1,2)
 --------------------
                    3
 OLDEMO.ADDITION(1,2,3)
 ----------------------
                      6
Example:
 PROCEDURE p2                     PROCEDURE p1
 PROCEDURE p3                     PROCEDURE p2
                                  PROCEDURE p3
--PACKAGE SPECIFICATION
   PROCEDURE p1
   AS
   BEGIN
     dbms_output.put_line('p1 called');
   END p1;
   PROCEDURE p2
   AS
   BEGIN
     p1;
    ORACLE 6PM PLSQL Page 98
      p1;
      dbms_output.put_line('p2 called');
    END p2;
   PROCEDURE p3
   AS
   BEGIN
      p1;
      dbms_output.put_line('p3 called');
   END p3;
 END;
 /
Dropping package:
    Syntax:
    DROP PACKAGE <name>;
    Example:
    DROP PACKAGE hr;
user_prcoedures:
it maintains all procedures, functions and packages info.
    SELECT text
    FROM user_source
    WHERE name='HR';
ORACLE DB SERVER
                                                              INSTANCE          DB
                        EXEC p1
                        EXEC p2                                  p1            proc p1
                        .                                        p2            proc p2
                        .                                        .             .
                        EXC p10                                  .             .
                                                                 p10           proc p10
ORACLE DB SERVER
                                                               INSTANCE          DB
               EXEC demo.p1
                                                                demo            PACKAGE demo
               EXEC demo.p2                                                       proc p1
               .                                                                  proc p2
               .                                                                  .
                                                                                  .
               EXEC demo.p10                                                      proc p10
                                                                       PROCEDURE hike
                                                               calls
EXEC hike(7369,2000);                                                    --Statements
                                                                       TRIGGER t1
                                                      calls
    DML / DDL
                                                                         --Statements
    TRIGGER:
     • It is one ORACLE DB Object.
            Note:
             • To perform DMLs, we define PROCEDURE.
             • To control DMLs, we define TRIGGER.
                  Examples:
                  don't allow DMLs on SUNDAY
                                   ORACLE 6PM PLSQL Page 102
  don't allow DMLs on SUNDAY
  don't allow DMLs before or after office timings
  Example:
  which user
  on which date
  at which time
  which operations
  what was old data
  what is new data
  Example:
    don’t decrease emp salary
Types of Triggers:
3 Types:
      Example:
        UPDATE emp SET sal=sal+1000;          --1 time
      Example:
        UPDATE emp SET sal=sal+1000;          -- 14 times
        Output:
        14 rows updated
  Testing:
  UPDATE emp SET sal=sal+1000;
  Output:
  statement level trigger executed..
  14 rows updated.
  Testing:
  UPDATE emp SET sal=sal+1000;
  Output:
  row level trigger executed..
  row level trigger executed..
14 rows updated.
                  Syntax:
                    ALTER TRIGGER <name> DISABLE/ENABLE;
                  Example:
                    ALTER TRIGGER t1 DISABLE; --t1 trigger will not work
Dropping trigger:
                         Syntax:
                           DROP TRIGGER <name>;
                         Example:
                           DROP TRIGGER t1;
                Before trigger:
                 • first trigger code gets executed.
                 • then DML operation will be performed.
                After trigger:
                 • first DML operation will be performed.
                 • then trigger gets executed.
   CREATE TRIGGER t4
   BEFORE update OF empno
   ON emp
   BEGIN
     raise_application_error(-20050, 'you cannot update empno..');
   END;
   /
   Testing:
   update emp set empno=1234
   where empno=7499;
   Output:
   ERROR:
   ORA-20050: you cannot update empno..
EMP
EMPNO ENAME SAL
1001   A           5000
1002   B           6000
                                                  :new
                                              EMPNO ENAME SAL
INSERT INTO emp                               5001        AB      10000
VALUES(5001,'AB',10000);
                                                  :old
                                              EMPNO ENAME SAL
                                              null        null    null
                                                     :new
 DELETE FROM emp                              EMPNO ENAME SAL
 WHERE empno=1001;                            null        null    null
                                                        :old
                                              EMPNO ENAME SAL
                                              1001        A       5000
                                                 :old
                                                 EMPNO ENAME SAL
                                                 1002         B    6000
     Testing:
     DELETE FROM emp WHERE empno=7788;
     COMMIT;
Example:
EMP_AUDIT
uname op_date_time op_type old_empno old_ename old_Sal new_empno new_ename new_Sal
             ORACLE 6PM PLSQL Page 110
uname op_date_time op_type old_empno old_ename old_Sal new_empno new_ename new_Sal
user     systimestamp op                :old.empno :old.ename :old.sal :new.empno :new.ename :new.sal
        Example:
        define a trigger to don't allow the user to decrease the
        salary:
• it is developed by DBA.
Syntax:
  login as DBA:
     username: system
     password: naresh
  Testing:
  DROP TABLE salgrade;
  Output:
  ERROR:
  ORA-20050: you cannot drop any db object..
Testing:
DROP TABLE salgrade;
Output:
ERROR:
ORA-20050: you cannot drop table..
• it is developed by DBA.
Note:
to control 1 user define SCHEMA LEVEL TRIGGER
to control multiple users or all users define DATABASE LEVEL TRIGGER
Syntax:
Testing:
login as c##batch730am:
login as c##batch2pm:
 user_triggers:
 it maintains all triggers info
DESC user_triggers
    SELECT text
    FROM user_Source
    WHERE name='T6';
                     COLLECTION:
                      • COLLECTION is a set of elements of same type.
                     Examples:
                                                                      STUDENT%ROWTYPE
                NUMBER                             VARCHAR2
                                                                      s
                  x                                   a
                                                                      SID   SNAME SCITY
                                                                                          s(1)
                          45                           SMITH          1001 A       HYD
                          56                           ALLEN
                          32                           MILLER         SID   SNAME SCITY   s(2)
                          89                           SCOTT          1002 B       DLH
Types of Collections:
                3 Types:
                 • Associative Array / PL SQL Table / Index By Table
                 • Nested table
                 • V-Array
            Associative Array:
             • ASSOCIATIVE ARRAY is a table of 2 columns. They are:
               INDEX
               ELEMENT
                          x                     a
  2 steps:
   ○ define the data type
   ○ declare variable for that data type
     Syntax:
       TYPE <name> IS TABLE OF <element_type>
       INDEX BY <index_type>;
                                                            x
     Example:
       TYPE num_array IS TABLE OF number(4)
                                                       INDEX ELEMENT
       INDEX BY binary_integer;
                                                       1    10
                                                       2    50
       Note:                                           3    30
       If INDEX is NUMBER type then                    4    90
       we can use binary_integer or
       pls_integer
    Syntax:
      <variable> <data_type>;
    Example:
      x num_array;
DECLARE
  TYPE num_array IS TABLE OF number(4)
  INDEX BY binary_integer;
                                                                  x
  x num_array;                                                INDEX ELEMENT
BEGIN
                                                              1       10
  x := num_array(10,50,30,90);           --21C
                                                              2       50
    /* x(1):=10;                                              3       30
       x(2):=20;                                              4       90
       x(3):=30;
       x(4):=90;        */               --19c
collection constructor:
 • is a special function.
 • is used to initialize the collection.
 • initializing collection means bringing values into collection.
Collection members:
DECLARE
  TYPE dept_array IS TABLE OF varchar2(10)
  INDEX BY binary_integer;
  d DEPT_ARRAY;
BEGIN
  SELECT dname INTO                      d(1)   FROM   dept   WHERE   deptno=10;
  SELECT dname INTO                      d(2)   FROM   dept   WHERE   deptno=20;
  SELECT dname INTO                      d(3)   FROM   dept   WHERE   deptno=30;
  SELECT dname INTO                      d(4)   FROM   dept   WHERE   deptno=40;
END;
/
Output:
ACCOUNTING
RESEARCH
SALES
OPERATIONS
                                       PL/SQL Engine
  PL/SQL program
  SQL statements
                                       PL/SQL stmt executor
  +
  PL/SQL statements
                                                  context switch
                                       SQL stmt executor
BULK COLLECT:
 • BULK COLLECT clause is used to collect entire data at
   a time with single context switch.
 • It improves the performance.
 • It reduces no of context switches and improves the
   performance.
DECLARE
  TYPE dept_array IS TABLE OF varchar2(10)
  INDEX BY binary_integer;
END;
/
Output:
ACCOUNTING
RESEARCH
SALES
OPERATIONS
 DECLARE
   TYPE emp_array IS TABLE OF emp%rowtype
   INDEX BY binary_integer;
    e EMP_ARRAY;
            ORACLE 6PM PLSQL Page 121
  e EMP_ARRAY;
BEGIN
  SELECT * BULK COLLECT INTO e FROM emp;
  FOR i IN e.first..e.last
  LOOP
  dbms_output.put_line(e(i).ename || '     ' || e(i).sal);
  END LOOP;
END;
/
   EMPLOYEE                              HIKE
   EMPNO ENAME SAL                       EMPNO PER
   1001        A               5000      1001    10
   1002        B               3000      1002    20
   1003        C               7000      1003    15
                                            h
HIKE
                                    INDEX       ELEMENT
EMPNO PER
1001   10                                        EMPNO PER
1002   20                             1          1001   10
1003   15
                                                 EMPNO PER
                                      2
                                                 1002   20
                                                 EMPNO PER
                                      3
                                                 1003   15
 DECLARE
   TYPE hike_array IS TABLE OF hike%rowtype
   INDEX BY binary_integer;
   h HIKE_ARRAY;
 BEGIN
   SELECT * BULK COLLECT INTO h FROM hike;
   COMMIT;
   dbms_output.put_line('sal increased to all emps..');
 END;
 /
 BULK BIND:
        ORACLE 6PM PLSQL Page 123
BULK BIND:
 • BULK BIND is used to submit BULK INSERT / BULK
   UPDATE / BULK DELETE commands.
Note:
We will not use BULK BIND keyword to use BULK BIND.
Just we define FORALL loop.
  Syntax:
    FORALL <varibale> IN <lower> .. <upper>
      --DML statement
  Example:
    FORALL i IN h.first .. h.last
    UPDATE employee SET sal=sal+sal*h(i).per/100
    WHERE empno=h(i).empno;
 DECLARE
   TYPE hike_array IS TABLE OF hike%rowtype
   INDEX BY binary_integer;
   h HIKE_ARRAY;
 BEGIN
   SELECT * BULK COLLECT INTO h FROM hike;
   COMMIT;
   dbms_output.put_line('sal increased to all emps..');
 END;
 /
Example:
      ELEMENT
      10
      50
      30
      90
 2 steps:
  • create our own data type
  • declare variable for that data type
      Syntax:
        TYPE <name> IS TABLE OF <element_type>;
      Example:
        TYPE num_array IS TABLE OF number(4);
      Syntax:
        <variable> <data_type>;
      Example:
        x NUM_ARRAY;
       DECLARE
         TYPE num_array IS TABLE OF number(4);
         x NUM_ARRAY;
       BEGIN
         x := num_array(10,50,30,90);
DECLARE
  TYPE emp_array IS TABLE OF emp%rowtype;
  e EMP_ARRAY;
BEGIN
  SELECT * BULK COLLECT INTO e FROM emp;
END;
/
V-ARRAY:
 • V-ARRAY => variable size array
 • It is same as nested table. But, it can hold limited
   number of elements.
Creating V-array:
2 steps:
   create our own data type
    Syntax:
      TYPE <name> IS VARRAY(<size>) OF <element_type>;
    Example:
      TYPE num_array IS VARRAY(10) OF number(4);
    Syntax:
      <variable> <data_type>
    Example:
      x num_array;
Example on v-array:
     DECLARE
       TYPE num_array IS VARRAY(10) OF number(4);
       x num_array;
     BEGIN
       x := num_array(10,50,30,90);
DECLARE
         e EMP_ARRAY;
       BEGIN
         SELECT * BULK COLLECT INTO e FROM emp;
         FOR i IN e.first..e.last
         LOOP
         dbms_output.put_line(e(i).ename || '       ' || e(i).sal);
         END LOOP;
       END;
       /
CURSOR COLLECTION
                                         • COLLECTION is Faster
• CURSOR is slower
                         x(1)                   x(10)
                         x(2)                   x(20)
                         x(3)                   x(50)
                         x(4)                   x(90)
                         x(5)
        BFILE:
         • BFILE => Binary File Large Object
         • It is a pointer to multimedia object.
         • It is used to maintain multimedia object's path.
         • It can be also called as "External Large Object".
         • It is not secured one.
Example:
                                                                           D1 = D:\ Photos
                        DB
                                                                               D:
         EMP1                                                                       Photos
               EMPNO ENAME EPHOTO [BFILE]
               1234              Ravi         bfilename('D1','ravi.jpg')
                                                                                      ravi.jpg
        Directory Object:
         • Directory object is a pointer to specific folder.
         • DBA creates it.
              Syntax:
                CREATE DIRECTORY <dir_obj_name> AS <folder_path>;
  Example:
    login as DBA:
    username: system
    password: naresh
Example on BFILE:
  EMP1
    EMPNO ENAME EPHOTO [BFILE]
COMMIT;
  BLOB:
    BLOB => Binary Large Object
 Example:                  DB
                                                       D:
 EMP2                                                       PHOTOS
 EMPNO ENAME                 EPHOTO [BLOB]
 1234      ELLISON 67567AB565EF675
ellison.jpg
Example on BLOB:
  EMP2
  EMPNo ENAME EPHOTO [BLOB]
COMMIT;
UPDATE emp2 SET ephoto=t WHERE empno=p_empno; --t image stores in table
COMMIT;
  dbms_output.put_line('image updated...');
END;
/
LENGTH(EPHOTO)
--------------
          6638
DYNAMIC SQL:
    Calling:
    EXEC drop_table('salgrade');
    Output:
    salgrade table dropped..
Calling:
SQL> EXEC drop_object('procedure','addition');
Output:
addition procedure dropped..