Monday, April 11, 2011

PL/SQL Tutorial

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

Lesson 1-2 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

<<OUTER>>
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 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 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 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

Auto Scroll Stop Scroll