What is PL/SQL?
Procedural Language extension to SQL
It integrates procedural constructs with SQL
SET SERVEROUTPUT ON
This command is used to send the output from the server to the screen

Introduction & Declaring PL/SQL Identifiers
SQL> SET SERVEROUTPUT ON
Program1: Printing a String
BEGIN
dbms_output.put_line ('Welcome to PL/SQL');
END;
/
Output:
Welcome to PL/SQL
Program2:
Declaring the variable & Initializing the variable in the declare section
DECLARE
v_name VARCHAR2 (10) := 'Star';
BEGIN
dbms_output.put_line (v_name);
END;
/
Output:
Star
Program3:
Declaring the variable in declare section & initializing the variable in the executable section
DECLARE
v_name VARCHAR2 (10);
BEGIN
dbms_output.put_line ('Name is ' || v_name);
v_name := 'Star';
dbms_output.put_line ('Name is ' || v_name);
END;
/
Output:
Name is
Name is Star
Program4: Modifying the variable value in the Executable Section
DECLARE
v_name VARCHAR2 (10) := 'Star';
BEGIN
dbms_output.put_line ('Previous Value ' || v_name);
v_name := 'PLSQL Star';
dbms_output.put_line ('Modified to '|| v_name);
END;
/
Output:
Previous Value Star
Modified to PLSQL Star
Program5: Defining a Variable with Not Null
DECLARE
v_no NUMBER (4) NOT NULL :=10;
BEGIN
dbms_output.put_line (v_no);
END;
/
Output:
10
Program6: Defining a Variable with a Constant Value
DECLARE
v_pi CONSTANT NUMBER (5, 2) := 3.14;
BEGIN
dbms_output.put_line (v_pi);
END;
/
Output:
3.14
Program7: Defining a Variable with DEFAULT
DECLARE
v_no NUMBER (5) default 10;
BEGIN
dbms_output.put_line (v_no);
END;
/
Output:
10
Program8: Writing a PL/SQL Statement (INTO Clause)
DECLARE
v_sal NUMBER (5);
BEGIN
SELECT salary
INTO v_sal
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_sal);
END;
/
Output:
17000
Program9: Importance of %type with Scalar Variable (Variable Size is less)
DECLARE
v_sal NUMBER (2);
BEGIN
SELECT salary
INTO v_sal
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_sal);
END;
/
Output:
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: number precision too large
ORA-06512: at line 4
Program10: Usage of %type with Scalar Variable
DECLARE
v_sal employees.salary%type;
BEGIN
SELECT salary INTO v_sal
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_sal);
END;
/
Output:
17000
Program11: Assigning a Previously defined variable data type to a new variable by using %TYPE
DECLARE
v_name VARCHAR2 (10) := 'star';
v_job v_name%type := 'clerk';
BEGIN
dbms_output.put_line (v_name);
dbms_output.put_line (v_job);
END;
/
Output:
star
clerk
Program12: Bind Variable
VARIABLE g_sal NUMBER
BEGIN
SELECT salary
INTO :g_sal
FROM employees
WHERE employee_id=101;
END;
/
PRINT g_sal
Output:
     G_SAL
----------
     17000
SET AUTOPRINT ON
BEGIN
SELECT salary
INTO :g_sal
FROM employees
WHERE employee_id=101;
END;
/
Output:
     G_SAL
----------
     17000
Program13: Usage of Substitution Variable (&) with Scalar Variable
DECLARE
v_sal employees.salary%type;
BEGIN
SELECT salary
INTO v_sal
FROM employees
WHERE employee_id=&NO;
dbms_output.put_line (v_sal);
END;
/
Output:
Enter value for no: 100
old   7: WHERE employee_id=&NO;
new   7: WHERE employee_id=100;
24000
Program14: Usage of Substitution Variable (&&) with Scalar Variable
DECLARE
v_sal employees.salary%type;
BEGIN
SELECT salary
INTO v_sal
FROM employees
WHERE employee_id=&&NO2;
dbms_output.put_line (v_sal);
END;
/
Output:
Enter value for no2: 102
old   7: WHERE employee_id=&&NO2;
new   7: WHERE employee_id=102;
17000
Program15: DEFINE Variable
DEFINE no3=110
DECLARE
v_sal employees.salary%type;
BEGIN
SELECT salary INTO v_sal
FROM employees
WHERE employee_id=&no3;
dbms_output.put_line (v_sal);
END;
/
Output:
old   6: WHERE employee_id=&no3;
new   6: WHERE employee_id=110;
8200
Lesson 3-4: Writing Executable Statements & Interacting with the Oracle Server
Program1: Usage of a Single Row Function (LOWER) with a Scalar Variable
DECLARE
v_in_name VARCHAR2 (20):= 'STAR';
v_out_name VARCHAR2 (20);
BEGIN
v_out_name:= LOWER (v_in_name);
dbms_output.put_line (v_out_name);
END;
/
Output:
star
Program2: Usage of a Single Row Function (LENGTH) with a Scalar Variable
DECLARE
v_in_name VARCHAR2 (20) := 'STAR';
BEGIN
v_in_name := LENGTH(v_in_name);
dbms_output.put_line(v_in_name);
END;
/
Output:
4
Program3: Usage of a Single Row Function (TO_CHAR) with a Scalar Variable
 DECLARE
v_date DATE := sysdate;
v_out VARCHAR2 (50);
BEGIN
v_out := TO_CHAR(sysdate,'dd-mon-year');
dbms_output.put_line (v_out);
END;
/
Output:
27-jan-twenty eleven
Program4: NESTED BLOCK
DECLARE
outer_block VARCHAR2 (30) := 'Global_Variable';
BEGIN
        DECLARE
        inner_block VARCHAR2 (30) := 'Inner_Variable';
        BEGIN
        dbms_output.put_line (outer_block);
        dbms_output.put_line (inner_block);
        END;
dbms_output.put_line (outer_block);
END;
/
Output:
Global_Variable
Inner_Variable
Global_Variable
Program5: NESTED BLOCK with Label
<>
DECLARE
outer_block VARCHAR2 (30) := 'Global_Variable';
BEGIN
         DECLARE
         inner_block VARCHAR2 (30) := 'Inner_Variable';
         outer_block VARCHAR2 (30) := 'Inner_Variable without label';
         BEGIN
         dbms_output.put_line (outer_block);
         dbms_output.put_line (inner_block);
         dbms_output.put_line (OUTER.outer_block);
         END;
dbms_output.put_line (outer_block);
END;
/
Output:
Inner_Variable without label
Inner_Variable
Global_Variable
Global_Variable
Program6: Comments (Single Line Comment)
DECLARE
-- Single Line Comment
v_no NUMBER (4);
BEGIN
v_no:= 5*6;
dbms_output.put_line (v_no);
END;
/
Output:
30
Program7: Multiple Line Comment
DECLARE
v_no NUMBER(4);
BEGIN
/* Multiple Line Commenting here we will multiply
And place the result in the v_no */
v_no:= 5*6;
dbms_output.put_line (v_no);
END;
/
Output:
30
Program23: Using the Group Function in PL/SQL Statement
DECLARE
v_sal employees.salary%type;
BEGIN
SELECT SUM (salary)
INTO v_sal
FROM employees
WHERE department_id=60;
dbms_output.put_line(v_sal);
END;
/
Output:
28800
Program24: Usage of %ROWCOUNT Cursor Attribute
DROP TABLE emp PURGE;
CREATE TABLE emp AS
SELECT * FROM EMPLOYEES;
SELECT COUNT (*) FROM emp;
Output:
 COUNT (*)
----------
       107
DECLARE
v_del_rows NUMBER (4);
BEGIN
DELETE emp;
v_del_rows:= SQL%rowcount;
dbms_output.put_line (v_del_rows);
END;
/
Output:
107
Lesson 5-6 Writing Control Structures & Working with Composite Data types
Program1: Usage of IF statement
DECLARE
v_myage NUMBER := 31;
BEGIN
IF v_myage <11 span="" then="">
dbms_output.put_line (' I am a child ');
END IF;
END;
/
Output:
Program2: Usage of IF THEN ELSE statement
DECLARE
v_myage NUMBER := 31;
BEGIN
IF v_myage < 11 THEN
dbms_output.put_line (' I am a child ');
ELSE
dbms_output.put_line (' I am not a child');
END IF;
END;
/
Output:
I am not a child
Program3: Usage of IF ELSIF ELSE Clause
DECLARE
v_myage NUMBER := 31;
BEGIN
IF v_myage < 11 THEN
dbms_output.put_line (' I am a child ');
ELSIF v_myage < 20 THEN
dbms_output.put_line (' I am young');
ELSIF v_myage < 30 THEN
dbms_output.put_line (' I am in twenties');
ELSIF v_myage < 40 THEN
dbms_output.put_line (' I am in fourties');
ELSE
dbms_output.put_line (' I am always young');
END IF;
END;
/
Output:
I am in four ties
Program4: CASE statement
DECLARE
v_grade CHAR (1) := UPPER ('&grade');
v_appraisal VARCHAR2 (20);
BEGIN
v_appraisal :=
        CASE v_grade
        WHEN 'A' then 'Excellent'
        WHEN 'B' then 'Very Good'
        WHEN 'C' then 'Good'
        ELSE  'no such grade'
        END;
dbms_output.put_line (v_appraisal);
END;
/
Output:
Enter value for grade: A
old   2: v_grade CHAR (1) := UPPER ('&grade');
new   2: v_grade CHAR (1) := UPPER ('A');
Excellent
Program5: SEARCHED CASE
DECLARE
v_grade CHAR (1) := UPPER ('&grade');
v_appraisal VARCHAR2 (20);
BEGIN
v_appraisal :=
        CASE
        WHEN v_grade='A' then 'Excellent'
        WHEN v_grade='B' then 'Very Good'
        WHEN v_grade IN ('C','D') then 'Good'
        ELSE 'no such grade'
        END;
dbms_output.put_line (v_appraisal);
END;
/
Output:
Enter value for grade: A
old   2: v_grade CHAR (1) := UPPER ('&grade');
new   2: v_grade CHAR (1) := UPPER ('A');
Excellent
Program6: Handing NULL Value
DECLARE
v_name VARCHAR2 (10);
BEGIN
IF NOT (v_name) = 'star' then
dbms_output.put_line ('Welcome');
else
Dbms_ output.put_line ('working');
END IF;
END;
/
Output:
working
Program7: Usage of Simple LOOP
DECLARE
v_count NUMBER (2):= 1;
BEGIN
LOOP
dbms_output.put_line (v_count);
v_count := v_count+1;
EXIT WHEN v_count>5;
END LOOP;
END;
/
Output:
1
2
3
4
5
Program8: Usage of Simple LOOP
DECLARE
v_count NUMBER (2):= 10;
BEGIN
LOOP
dbms_output.put_line (v_count);
v_count := v_count+1;
exit when v_count>5;
END LOOP;
END;
/
Output:
10
Program9: Usage of a WHILE Loop
DECLARE
v_count NUMBER (2) :=1;
BEGIN
WHILE v_count < 3 loop
dbms_output.put_line (v_count);
v_count := v_count+1;
END LOOP;
END;
/
Output:
1
2
Program10: Usage of a FOR Loop in Ascending Order
BEGIN
FOR I in 1..5 LOOP
dbms_output.put_line (I);
END LOOP;
END;
/
Output:
1
2
3
4
5
Program11: Usage of a FOR Loop in Descending Order
BEGIN
FOR I in REVERSE 1..5 LOOP
dbms_output.put_line (I);
END LOOP;
END;
/
Output:
5
4
3
2
1
Program12: Usage of a PL/SQL Record
DECLARE
TYPE emp_rec IS RECORD
(
v_name VARCHAR2 (10),
v_date DATE
);
v_rec emp_rec;
BEGIN
SELECT last_name, hire_date
INTO v_rec
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_rec.v_name);
dbms_output.put_line (v_rec.v_date);
END;
/
Output:
Kochhar
21-SEP-89
Program13: Usage of a %ROWTYPE
DECLARE
emp_rec employees%ROWTYPE;
BEGIN
SELECT *
INTO emp_rec
FROM employees
WHERE employee_id=101;
dbms_output.put_line (emp_rec.last_name);
dbms_output.put_line (emp_rec.salary);
END;
/
Output:
17000
 Program14:  Usage of a DEFINE command
DEFINE countryid = CA
DECLARE
country_record countries%ROWTYPE;
BEGIN
SELECT *
INTO country_record
FROM countries
WHERE country_id=UPPER('&countryid');
DBMS_OUTPUT.PUT_LINE('Country Id: ' || country_record.country_id || 'Country Name: ' || country_record.country_name || ' Region: ' || country_record.region_id);
END;
/
Output:
old   7: WHERE country_id=UPPER('&countryid');
new   7: WHERE country_id=UPPER('CA');
Country Id: CACountry Name: Canada Region: 2
Program15: Usage of INDEX BY TABLE with %TYPE
DECLARE
TYPE emp_tab IS TABLE OF
employees.last_name%type
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT last_name INTO v_emp (1)
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_emp (1));
END;
/
Output:  Kochhar
Program16: Usage of INDEX BY TABLE with %TYPE
DECLARE
TYPE dept_table_type
IS TABLE OF
departments.department_name%TYPE
INDEX BY PLS_INTEGER;
my_dept_table   dept_table_type;
loop_count NUMBER(2) :=10;
deptno NUMBER(4) := 0;
BEGIN
FOR i IN 1..loop_count LOOP
deptno:=deptno+10;
SELECT department_name
INTO my_dept_table(i)
FROM departments
WHERE department_id = deptno;
 dbms_output.put_line(my_dept_table(i));
END LOOP;
END;
/
Output:
Administration
Marketing
Purchasing
Human Resources
Shipping
IT
Public Relations
Sales
Executive
Finance
Program17: Usage of INDEX BY TABLE with %TYPE
DECLARE
TYPE dept_table_type
IS TABLE OF
departments.department_name%TYPE
INDEX BY PLS_INTEGER;
my_dept_table   dept_table_type;
loop_count NUMBER(2) :=10;
deptno NUMBER(4) := 0;
BEGIN
FOR i IN 1..loop_count LOOP
deptno:=deptno+10;
SELECT department_name
INTO my_dept_table(i)
FROM departments
WHERE department_id = deptno;
END LOOP;
FOR i IN 1..loop_count
LOOP
dbms_output.put_line(my_dept_table(i));
END LOOP;
END;
/
Output:
Administration
Marketing
Purchasing
Human Resources
Shipping
IT
Public Relations
Sales
Executive
Finance
Program18: Usage of INDEX BY TABLE with %ROWTYPE
DECLARE
TYPE dept_table_type
IS TABLE OF
departments%ROWTYPE
INDEX BY PLS_INTEGER;
my_dept_table   dept_table_type;
loop_count NUMBER(2) :=10;
deptno NUMBER(4) := 0;
BEGIN
FOR i IN 1..loop_count LOOP
deptno:=deptno+10;
SELECT *
INTO my_dept_table(i)
FROM departments
WHERE department_id = deptno;
dbms_output.put_line(my_dept_table(i).department_name);
END LOOP;
END;
/
Output:
Administration
Marketing
Purchasing
Human Resources
Shipping
IT
Public Relations
Sales
Executive
Finance
Program19: Usage of INDEX BY TABLE with %ROWTYPE
DECLARE
TYPE dept_table_type
IS TABLE OF
departments%ROWTYPE
INDEX BY PLS_INTEGER;
my_dept_table   dept_table_type;
loop_count NUMBER(2) :=10;
deptno NUMBER(4) := 0;
BEGIN
FOR i IN 1..loop_count LOOP
deptno:=deptno+10;
SELECT *
INTO my_dept_table(i)
FROM departments
WHERE department_id = deptno;
END LOOP;
FOR i IN 1..loop_count
LOOP
dbms_output.put_line('Department Number: ' || my_dept_table(i).department_id || ' Department Name: ' || my_dept_table(i).manager_id || ' Location Id: ' || my_dept_table(i).location_id);
END LOOP;
END;
/
Output:
Department Number: 10 Department Name: 200 Location Id: 1700
Department Number: 20 Department Name: 201 Location Id: 1800
Department Number: 30 Department Name: 114 Location Id: 1700
Department Number: 40 Department Name: 203 Location Id: 2400
Department Number: 50 Department Name: 121 Location Id: 1500
Department Number: 60 Department Name: 103 Location Id: 1400
Department Number: 70 Department Name: 204 Location Id: 2700
Department Number: 80 Department Name: 145 Location Id: 2500
Department Number: 90 Department Name: 100 Location Id: 1700
Department Number: 100 Department Name: 108 Location Id: 1700
Program20: Usage of INDEX BY TABLE with %TYPE
DECLARE
TYPE emp_tab IS TABLE OF
employees.last_name%type
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT last_name INTO v_emp (1)
FROM employees
WHERE employee_id=101;
SELECT last_name INTO v_emp (2)
FROM employees
WHERE employee_id=102;
dbms_output.put_line (v_emp (1));
dbms_output.put_line (v_emp (2));
END;
/
Output:
Kochhar
De Haan
Program21: Usage of INDEX BY TABLE with %ROWTYPE
DECLARE
TYPE emp_tab IS TABLE OF
employees%rowtype
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT * INTO v_emp (1)
FROM employees
WHERE employee_id=101;
SELECT * INTO v_emp (2)
FROM employees
WHERE employee_id=102;
dbms_output.put_line (v_emp (1).last_name || ' job ' || v_emp (1).job_id);
dbms_output.put_line (v_emp (2).last_name || ' job ' || v_emp (2).job_id);
END;
/
Output:
Kochhar job AD_VP
De Haan job AD_VP
Program22: Usage of INDEX BY TABLE with %ROWTYPE with EXISTS Method
DECLARE
TYPE emp_tab IS TABLE OF
employees%rowtype
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT * INTO v_emp (1)
FROM employees
WHERE employee_id=101;
SELECT * INTO v_emp (2)
FROM employees
WHERE employee_id=102;
IF v_emp.EXISTS (1) THEN
dbms_output.put_line (v_emp (1).last_name || ' job ' || v_emp (1).job_id);
END IF;
dbms_output.put_line (v_emp (2).last_name || ' job ' || v_emp (2).job_id);
END;
/
Output:
Kochhar job AD_VP
De Haan job AD_VP
Program23: Usage of INDEX BY TABLE with %ROWTYPE with COUNT Method
DECLARE
TYPE emp_tab IS TABLE OF
employees%rowtype
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT * INTO v_emp (1)
FROM employees
WHERE employee_id=101;
SELECT * INTO v_emp (2)
FROM employees
WHERE employee_id=102;
dbms_output.put_line (' counting ' || v_emp.count);
dbms_output.put_line (v_emp (1).last_name || ' job ' || v_emp (1).job_id);
dbms_output.put_line (v_emp (2).last_name || ' job ' || v_emp (2).job_id);
END;
/
Output:
Counting 2
Kochhar job AD_VP
De Haan job AD_VP
Program24: Usage of INDEX BY TABLE with %ROWTYPE with PRIOR Method
DECLARE
TYPE emp_tab IS TABLE OF
employees%rowtype
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT * INTO v_emp (1)
FROM employees
WHERE employee_id=101;
SELECT * INTO v_emp (2)
FROM employees
WHERE employee_id=102;
dbms_output.put_line (' prior ' || v_emp.prior (2));
dbms_output.put_line (v_emp (1).last_name || ' job ' || v_emp (1).job_id);
dbms_output.put_line (v_emp (2).last_name || ' job ' || v_emp (2).job_id);
END;
/
Output:
Prior 1
Kochhar job AD_VP
De Haan job AD_VP
Program25: Usage of INDEX BY TABLE with %ROWTYPE with NEXT Method
DECLARE
TYPE emp_tab IS TABLE OF
employees%rowtype
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
SELECT * INTO v_emp (1)
FROM employees
WHERE employee_id=101;
SELECT * INTO v_emp (2)
FROM employees
WHERE employee_id=102;
dbms_output.put_line (' Next ' || v_emp.next(1));
dbms_output.put_line (v_emp (1).last_name || ' job ' || v_emp (1).job_id);
dbms_output.put_line (v_emp (2).last_name || ' job ' || v_emp (2).job_id);
END;
/
Output:
Next 2
Kochhar job AD_VP
De Haan job AD_VP
Program26: Usage of INDEX BY TABLE with %ROWTYPE with FIRST..LAST Method
DECLARE
TYPE emp_tab IS TABLE OF
employees%rowtype
INDEX BY PLS_INTEGER;
v_emp emp_tab;
BEGIN
FOR I in 100..104 LOOP
SELECT * INTO v_emp (I) FROM employees WHERE employee_id=I;
END LOOP;
FOR I IN v_emp.FIRST..v_emp.LAST LOOP
dbms_output.put_line (v_emp (i).first_name || ' last name is ' || v_emp (i).last_name);
END LOOP;
END;
/
Output:
Steven last name is King
Neena last name is Kochhar
Lex last name is De Haan
Alexander last name is Hunold
Bruce last name is Ernst
Lesson 7-8 (Cursors & Exceptions)
Program1: Usage of %NOTFOUND Cursor Attribute
DECLARE
v_name VARCHAR2 (20);
CURSOR v_cur IS
SELECT first_name
FROM employees;
BEGIN
OPEN v_cur;
LOOP
FETCH v_cur INTO v_name;
dbms_output.put_line (v_name);
EXIT WHEN v_cur%NOTFOUND;
END LOOP;
CLOSE v_cur;
END;
/
Output:
Alana
Matthew
Jennifer
Eleni
Eleni
Program2: Usage of %FOUND Cursor Attribute
DECLARE
v_name VARCHAR2 (20);
CURSOR v_cur IS
SELECT first_name
FROM employees;
BEGIN
OPEN v_cur;
LOOP
FETCH v_cur INTO v_name;
dbms_output.put_line (v_name);
EXIT WHEN v_cur%FOUND;
END LOOP;
CLOSE v_cur;
END;
/
Output:          Ellen
Program3: Usage of %ROWCOUNT Cursor Attribute
DECLARE
v_name VARCHAR2 (20);
CURSOR v_cur IS
SELECT first_name
FROM employees;
BEGIN
OPEN v_cur;
LOOP
FETCH v_cur INTO v_name;
dbms_output.put_line (v_name);
EXIT WHEN v_cur%ROWCOUNT>5;
END LOOP;
CLOSE v_cur;
END;
/
Output:
Ellen
Sundar
Mozhe
David
Hermann
Shelli
Program4: Usage of RECORD with Cursor
DECLARE
CURSOR v_cur IS
SELECT * FROM employees;
v_emp v_cur%ROWTYPE;
BEGIN
OPEN v_cur;
LOOP
FETCH v_cur INTO v_emp;
dbms_output.put_line (v_emp.first_name);
EXIT WHEN v_cur%ROWCOUNT>5;
END LOOP;
CLOSE v_cur;
END;
/
Output:
Donald
Douglas
Jennifer
Michael
Pat
Susan
Program5: Usage of CURSOR FOR LOOP
DECLARE
CURSOR v_cur IS SELECT * FROM employees;
BEGIN
FOR v_emp IN v_cur LOOP
dbms_output.put_line (v_emp.first_name);
END LOOP;
END;
/
Output:
Samuel
Vance
Alana
Kevin
Program6: Usage of CURSOR FOR LOOP WITH sub query
BEGIN
FOR v_emp IN (SELECT * FROM EMPLOYEES) LOOP
dbms_output.put_line (v_emp.first_name);
END LOOP;
END;
/
Output:
Samuel
Vance
Alana
Kevin
Program7: Usage of Cursor with Parameters
DECLARE
CURSOR c1 (p_deptno IN NUMBER, p_job IN VARCHAR2) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id=p_deptno AND job_id=p_job;
v1 c1%rowtype;
BEGIN
OPEN c1 (10,'AD_ASST');
LOOP
FETCH C1 INTO v1;
EXIT WHEN c1%notfound;
dbms_output.put_line ('dept10 details ' || v1.last_name);
END LOOP;
CLOSE C1;
OPEN c1 (20,'MK_MAN');
LOOP
FETCH C1 INTO v1;
EXIT WHEN c1%notfound;
dbms_output.put_line ('dept20 details ' || v1.last_name);
END LOOP;
CLOSE C1;
END;
/
Output:
dept10 details Whalen
dept20 details Hartstein
Program8: Usage of Cursor with FOR UPDATE OF Clause
SQL> select salary from employees where department_id=60;
 SALARY
---------
      9000
      6000
      4800
      4800
      4200
SQL> UPDATE employees
SET salary=4000
WHERE department_id=60;
Output:
5 rows updated.
DECLARE
CURSOR c1 IS
SELECT employee_id, salary
FROM employees
WHERE department_id=60
FOR UPDATE OF SALARY NOWAIT;
BEGIN
FOR emp_rec IN c1 LOOP
IF emp_rec.salary<5000 span="" then="">
UPDATE employees
SET salary=3000;
END IF;
END LOOP;
END;
/
SQL> select salary from employees where department_id=60;
    SALARY
---------------
      3000
      3000
      3000
      3000
      3000
Note :         Cursor can't move backward
SQL> ROLLBACK;
Rollback complete.
 SQL> select salary from employees where department_id=60;
    SALARY
-----------------
      9000
      6000
      4800
      4800
      4200
Program9: Usage of Cursor with FOR UPDATE OF, WHERE CURRENT OF Clause
DECLARE
CURSOR c1 IS
SELECT employee_id, salary
FROM employees
WHERE department_id=60
FOR UPDATE OF SALARY NOWAIT;
BEGIN
FOR emp_rec IN c1 LOOP
IF emp_rec.salary<5000 span="" then="">
UPDATE employees
SET salary=salary+999
WHERE CURRENT OF c1;
END IF;
END LOOP;
END;
/
SQL> select salary from employees where department_id=60;
   SALARY
-----------------
      9000
      6000
      5799
      5799
      5199
SQL> rollback;
Rollback complete.
Program10: Printing the ROWID value
DECLARE
v_row rowid;
v_empno employees.employee_id%type;
v_sal employees.salary%type;
CURSOR c1 IS
SELECT ROWID,employee_id, salary
FROM employees
WHERE department_id=60;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO v_row,v_empno,v_sal;
exit when c1%NOTFOUND;
dbms_output.put_line(v_row ||'-'||'-'||v_empno||'-'||v_sal);
END LOOP;
CLOSE c1;
END;
/
Output:   
 AAAMg3AAFAAAABYAAD--103-9000
AAAMg3AAFAAAABYAAE--104-6000
AAAMg3AAFAAAABYAAF--105-4800
AAAMg3AAFAAAABYAAG--106-4800
AAAMg3AAFAAAABYAAH--107-4200
SQL> rollback;
Rollback complete.
Program11: Implementing with ROWID (9i)
DECLARE
v_row rowid;
v_empno employees.employee_id%type;
v_sal employees.salary%type;
CURSOR c1 IS
SELECT ROWID,employee_id, salary
FROM employees
WHERE department_id=60;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO v_row,v_empno,v_sal;
dbms_output.put_line(v_row ||'-'||'-'||v_empno||'-'||v_sal);
IF V_SAL < 5000 THEN
update employees
set salary=salary+999
where rowid=v_row;
END IF;
exit when c1%NOTFOUND;
END LOOP;
CLOSE c1;
END;
/
Output:
AAAMg3AAFAAAABYAAD--103-9000
AAAMg3AAFAAAABYAAE--104-6000
AAAMg3AAFAAAABYAAF--105-4800
AAAMg3AAFAAAABYAAG--106-4800
AAAMg3AAFAAAABYAAH--107-4200
AAAMg3AAFAAAABYAAH--107-4200
Program12: Raising the Implicit Exception
SELECT first_name
FROM employees
WHERE first_name='John';
FIRST_NAME
-------------------
John
John
John
DECLARE
v_name VARCHAR2 (10);
BEGIN
SELECT first_name INTO v_name
FROM employees
WHERE first_name='John';
dbms_output.put_line (v_name);
END;
/
Output:
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4
Program13: Usage of TOO_MANY_ROWS Exception
DECLARE
v_name VARCHAR2 (10);
BEGIN
SELECT first_name INTO v_name
FROM employees
WHERE first_name='John';
dbms_output.put_line (v_name);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line ('Returning more than one row');
END;
/
Output:   Returning more than one row
Program14: Usage of VALUE_ERROR Exception
DECLARE
v_name VARCHAR2(3);
BEGIN
SELECT last_name INTO v_name
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_name);
EXCEPTION
WHEN VALUE_ERROR THEN
dbms_output.put_line ('Data type size is small');
END;
/
Output:  Data type size is small
Program15: Usage of ZERO_DIVIDE Exception
DECLARE
v_sal NUMBER;
BEGIN
SELECT salary/0 INTO v_sal
FROM employees
WHERE employee_id=101;
dbms_output.put_line (v_sal);
EXCEPTION
WHEN ZERO_DIVIDE THEN
dbms_output.put_line ('We cant divide by zero');
END;
/
Output:           We cant divide by zero
Program16: Usage of Non Predefined Exception
DECLARE
v_excep EXCEPTION;
PRAGMA EXCEPTION_INIT (v_excep,-6502);
v_name VARCHAR2 (2);
BEGIN
SELECT last_name INTO v_name
FROM employees
WHERE employee_id=101;
EXCEPTION
WHEN v_excep THEN
dbms_output.put_line ('Check the Variable Size');
END;
/
Output:               Check the Variable Size
Program17: Usage of Tracking the Error Number, Error Message
DECLARE
v_name VARCHAR2 (2);
v_err_num NUMBER;
v_err_mess VARCHAR2 (250);
BEGIN
SELECT last_name INTO v_name
FROM employees WHERE employee_id=101;
EXCEPTION
WHEN OTHERS THEN
v_err_num := SQLCODE;
v_err_mess := SQLERRM;
dbms_output.put_line (v_err_num);
dbms_output.put_line (v_err_mess);
END;
/
Output:
-6502
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Program18: Usage of User Defined Exception
DECLARE
v_excep EXCEPTION;
BEGIN
UPDATE employees
SET salary=8000
WHERE employee_id=1;
IF SQL%NOTFOUND THEN
RAISE v_excep;
END IF;
EXCEPTION
WHEN v_excep THEN
dbms_output.put_line ('Explicitly Raised Exception');
END;
/
Output:
Explicitly Raised Exception
Program19: Usage of RAISE_APPLICATION_ERROR
BEGIN
UPDATE employees
SET salary=8000
WHERE employee_id=1;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR (-20000,'Raising Error');
END IF;
END;
/
Output:
BEGIN
*
ERROR at line 1:
ORA-20000: Raising Error
ORA-06512: at line 6
Program20: Handling Multiple Exceptions in Exception Section
DROP TABLE messages PURGE;
SQL>CREATE TABLE MESSAGES
(
MESSAGE VARCHAR2 (250)
);
Table created.
SQL> DELETE FROM MESSAGES;
0 rows deleted.
SQL> DEFINE sal = 6000
DECLARE
ename employees.last_name%TYPE;
emp_sal employees.salary%TYPE := &sal;
BEGIN
SELECT last_name
INTO ename
FROM employees
WHERE salary = emp_sal;
INSERT INTO messages VALUES (ename || ' - ' || emp_sal);
EXCEPTION
WHEN no_data_found THEN
INSERT INTO messages VALUES
('No employee with a salary of '|| TO_CHAR (emp_sal));
WHEN too_many_rows THEN
INSERT INTO messages VALUES
('More than one employee with a salary of '||TO_CHAR (emp_sal));
WHEN others THEN
INSERT INTO messages VALUES
('Some other error occurred.');
END;
/
Output:
old   3: emp_sal employees.salary%TYPE := &sal;
new   3: emp_sal employees.salary%TYPE := 6000;
SQL> SELECT * FROM messages;
MESSAGE
--------------------------------------------------------
More than one employee with a salary of 6000
Program21: Child Record found exception
DECLARE
childrecord_exists EXCEPTION;
PRAGMA EXCEPTION_INIT (childrecord_exists, -02292);
BEGIN
DBMS_OUTPUT.PUT_LINE (' Deleting department 40........');
DELETE FROM departments
WHERE department_id=40;
EXCEPTION
WHEN childrecord_exists THEN
DBMS_OUTPUT.PUT_LINE (' Cannot delete this department. There are employees in this department
(child records exist.) ');
END;
/
Output:
Deleting department 40........
Cannot delete this department. There are employees in this department
(child records exist.)
Lesson 9-10 Procedures & Functions
Program1: Simple Procedure to display a String
CREATE OR REPLACE PROCEDURE p1
IS
BEGIN
dbms_output.put_line ('welcome to 1st Procedure');
END p1;
/
Output:
Procedure created.
Executing a procedure
SQL> exec p1;
welcome to 1st Procedure
Program2: Simple Procedure to display a String
CREATE PROCEDURE hello_again IS
BEGIN
DBMS_OUTPUT.PUT_LINE ('Hello World again');
END;
/
Output:
CREATE PROCEDURE hello_again IS
BEGIN
DBMS_OUTPUT.PUT_LINE ('Hello World again');
END;
/
Executing a procedure in a PL/SQL block
SQL> BEGIN
hello_again;
END;
Output:
Hello World again
Program66: Creating a Procedure with IN parameters (INSERT)
CREATE OR REPLACE PROCEDURE add_job
(
jobid jobs.job_id%TYPE,
jobtitle jobs.job_title%TYPE
)
IS
BEGIN
INSERT INTO jobs (job_id, job_title) VALUES (jobid, jobtitle);
COMMIT;
END add_job;
/
Executing a Procedure
SQL> EXECUTE add_job ('IT_DBA', 'Database Administrator');
PL/SQL procedure successfully completed.
SQL> SELECT *
FROM jobs
WHERE job_id = 'IT_DBA';
JOB_ID     JOB_TITLE                           MIN_SALARY MAX_SALARY
---------- ----------------------------------- ---------- ----------
IT_DBA     Database Administrator
Program67: Creating a Procedure with IN parameters (UPDATE) with Exception Handling
CREATE OR REPLACE PROCEDURE upd_job
(
jobid IN jobs.job_id%TYPE,
jobtitle IN jobs.job_title%TYPE
)
IS
BEGIN
UPDATE jobs
SET job_title = jobtitle
WHERE job_id = jobid;
          IF SQL%NOTFOUND THEN
          RAISE_APPLICATION_ERROR (-20202, 'No job updated.');
          END IF;
END upd_job;
/
Output:
Procedure created.
Executing a Procedure:
SQL> EXECUTE upd_job ('IT_DBA', 'Data Administrator');
PL/SQL procedure successfully completed.
SQL> SELECT * FROM jobs WHERE job_id = 'IT_DBA';
JOB_ID     JOB_TITLE                           MIN_SALARY MAX_SALARY
---------- ----------------------------------- ---------- ----------
IT_DBA     Data Administrator
SQL> EXEC upd_job ('IT_WEB', 'Web Master');
SQL> EXEC upd_job ('IT_WEB', 'Web Master');
BEGIN upd_job ('IT_WEB', 'Web Master'); END;
*
ERROR at line 1:
ORA-20202: No job updated.
ORA-06512: at "HR.UPD_JOB", line 12
ORA-06512: at line 1
Program: 68
Creating a Procedure with IN parameters (DELETE) with Exception Handling
CREATE OR REPLACE PROCEDURE del_job
(
jobid jobs.job_id%TYPE
)
IS
BEGIN
DELETE FROM jobs
WHERE job_id = jobid;
          IF SQL%NOTFOUND THEN
          RAISE_APPLICATION_ERROR (-20203, 'No jobs deleted.');
          END IF;
END DEL_JOB;
EXECUTE del_job ('IT_DBA')
SELECT * FROM jobs WHERE job_id = 'IT_DBA';
SQL> EXECUTE del_job ('IT_WEB');
BEGIN del_job ('IT_WEB'); END;
*
ERROR at line 1:
ORA-20203: No jobs deleted.
ORA-06512: at "HR.DEL_JOB", line 11
ORA-06512: at line 1
Program69: Creating a Procedure with IN parameter along with local variables
CREATE OR REPLACE PROCEDURE P1
(
P_NO IN NUMBER
)
IS
v_name VARCHAR2 (10);
BEGIN
SELECT first_name
INTO v_name
FROM employees
WHERE employee_id=P_NO;
dbms_output.put_line (v_name);
END;
/
Output:
Executing a procedure:
EXEC P1 (100);
Program70: Procedure with Cursors
CREATE OR REPLACE PROCEDURE P1
IS
CURSOR emp_cursor IS SELECT * FROM employees;
BEGIN
FOR emp_rec IN emp_cursor LOOP
dbms_output.put_line (emp_rec.employee_id);
END LOOP;
END;
EXEC p1;
Program: 71
Procedure with OUT Parameter (Use Bind variable for OUT Parameter)
CREATE OR REPLACE PROCEDURE p1
(P_NO IN NUMBER, P_JOB OUT VARCHAR2, P_SAL OUT NUMBER)
IS
BEGIN
SELECT job_id, salary
INTO P_JOB, P_SAL
FROM employees
W HERE employee_id=P_NO;
END p1;
Procedure Created
SQL> variable g_job VARCHAR2 (20)
SQL> variable g_sal varchar2 (20)
SQL> exec p1 (100, :g_job, :g_sal);
SQL> print g_job g_sal
Program72: Procedure with OUT Parameter (Use Bind variable for OUT Parameter) With Exception Handling
CREATE OR REPLACE PROCEDURE p1
(
P_NO IN NUMBER,
P_JOB OUT VARCHAR2,
P_SAL OUT NUMBER
)
IS
BEGIN
SELECT job_id, salary
INTO P_JOB, P_SAL
FROM employees
WHERE employee_id=P_NO;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line ('Check the Parameter Value');
END p1;
/
Variable g_job VARCHAR2(20)
Variable g_sal VARCHAR2(20)
EXEC p1 (10, :g_job, :g_sal);
Note:
A procedure can become invalid if the table it is based on is deleted or changed
We can recompile an invalid procedure using this command:
ALTER PROCEDURE procedure_name COMPILE;
Example1:
CREATE OR REPLACE FUNCTION f1
(
p_empno employee.employee_id%TYPE
)
RETURN varchar2
AS
v_name varchar2(50);
BEGIN
SELECT first_name
INTO v_name
FROM employees
WHERE employee_id=p_empno;
RETURN v_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN(‘The employee_id is not in the database');
WHEN OTHERS THEN
RETURN(‘Error in running function');
END;
/
EXEC f1;
Example:2
CREATE OR REPLACE FUNCTION id_is_good
(
p_empno IN NUMBER
)
RETURN BOOLEAN
AS
v_id_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_id_cnt
FROM employees
WHERE employee_id = p_empno;
RETURN 1 = v_id_cnt;
EXCEPTION
WHEN OTHERS THEN
RETURN FALSE;
END id_is_good;
/
DECLARE
v_id number;
BEGIN
v_id := &id;
IF id_is_good(v_id) THEN
DBMS_OUTPUT.PUT_LINE ('Student ID: '||v_id||' is a valid.');
ELSE
DBMS_OUTPUT.PUT_LINE ('Student ID: '||v_id||' is not valid.');
END IF;
END;

/

0 Comments:

Post a Comment