Sei sulla pagina 1di 92

PLSQL: Procedural Structured Query Language.

It is one of the comprehensive tools of the oracle that is helpful in adding the procedural language features such as Decision making, looping, exception handling etc... to the powerful SQL.

PLSQL Programs contains 3 sections. 1)Declaration section: In this section we declare the variables ,cursors etc 2)Executable section: In this section we do the looping, decision making and to the sq. statements 3)Exception section: In this section we handle the exceptions raised while using the sq. statements. Every plsql statement should be terminated with semi colon(;) Variable: A variable is a named location in memory to which a data can be assigned or from which the data can be read.

Variable declaration: A variable is declared in the declaration section for the process of telling the compiler,the name memory location its type and size.

Variable Declaration Syntax: Variable_name datatype(size); Ex: ln_num number; Ln_flag char(1); Ln_msg varchar2(10000);

Assigment Operator (:=) This operator is used to assign the value on its right to the variable on its left. EX: ln_num:= 0; Ln_falg:= N;
1

Intialization: This is process of assigning a variable an intial value at the time of declaration of the variable.

Ex: ln_num NUMBER:= 0; Ln_falg char(1):= N;

Server output: It is an sql environment variable that tells whether the output of the plsql program has to be shown, by default it is OFF; Inordet to ON please run the below command at the beginning of every session.

SET SERVEROUTPUT ON;

DBMS_OUTPUT.PUT_LINE: This is one of the built in package.function of the plsql that is used to print the output. BLOCKS: BLOCKS Reusability Stogare Scope NO Yes Until the session Permanently

Anonymous Not there Named Yes

Lets write some anonymous blocks to get practiced of how to print a message and use the variables and assign a value to it and also assign an intial value to it.
2

To Print a Message.

begin dbms_output.put_line('Welcome to Plsql'); end; /

declare ln_msg varchar2(1000); begin dbms_output.put_line('Start'); ln_msg:= 'Welcome to Plsql'; dbms_output.put_line(ln_msg); dbms_output.put_line('End'); end; /

declare ln_num number:=&parameter1; begin dbms_output.put_line('Start'); dbms_output.put_line(ln_num); dbms_output.put_line('End'); end; /

1) Addtion of 2 numbers. declare ln_num number:=0; ln_num1 number:=&parameter1; ln_num2 number:=&parameter2; begin dbms_output.put_line('Start'); ln_num := ln_num1 + ln_num2; dbms_output.put_line('The sum of '||ln_num1||' and '||ln_num2||' is '||chr(10)||ln_num); dbms_output.put_line('End'); end;

2) Substraction 2 numbers. 3) Addition of 2 numbers and substracting the 3 number. 4) Multiplication of 2 numbers.

Decision Making: If condition Syntax: IF condition1 then Statement1; ELSIF condition2 then Statement2; ELSIF condition3 then Statement3; ELSE Statement n; END IF;
4

5) Display Max of 2 numbers declare ln_num1 number:=&parameter1; ln_num2 number:=&parameter2; begin dbms_output.put_line('Start'); IF ln_num1 > ln_num2 then dbms_output.put_line('The smax number is '||ln_num1); else dbms_output.put_line('The smax number is '||ln_num2); end if; dbms_output.put_line('End'); end; / 7) Give input as 3 numbers and print the max number 8) Give input as 3 numbers and print the max number when added 2 numbers.

LOOPING: Syntax: FOR variable in start..end LOOP --any action to be taken place END LOOP; EX: 1) Print the numbers from 1 to 100/. declare i number:= 0; begin for i in 1..100 loop dbms_output.put_line('The number is ' ||i); end loop; end; 2) Print the odd numbers from 1 to 20. declare i number:= 0; begin for i in 1..20 loop if mod(i,2)!= 0 then dbms_output.put_line('The odd number is ' ||i); end if; end loop; end; /

3) print the even numbers from 1 to 20. declare i number:= 0; begin for i in 1..20 loop if mod(i,2) = 0 then dbms_output.put_line('The odd number is ' ||i); end if; end loop; end; /

EXIT: This is an oracle provided plsql keyword using which we can come out of the loop. EX: Print the odd numbers from 1 to 50 and exit when ever you find the number 26 in the loop.. declare i number:= 0; begin for i in 1..50 loop if i = 26 then exit; else if mod(i,2) != 0 then dbms_output.put_line('The odd number is ' ||i); end if; end if; end loop; dbms_output.put_line('The end '); end;

NOTE: Whenever we write a sql statement in a plsql block we cannot use the column name directly for any manipulation purpose etc. We should fetch the values in to the local variables using INTO Clause. Total No of column in the select clause should be equal to total number of variables in the into clause. The order of selected columns data type and size sequence should be same as the order of variables sequence data type and size in the into clause.

EX: Write a Simple plsql block to display employee name,number,salary.

declare ln_empno number:=0; ln_ename varchar2(100); ln_sal number; begin select empno,ename,sal into ln_empno,ln_ename,ln_sal from emp where empno = &parameter1; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); end; /

%TYPE: This attribute is used to declare the plsql variables with the same definition as column definition of a table.

Syntax: variable Name Table_Name.Column_Name%type;

EX: Write a Simple plsql block to display employee name,number,salary.

declare ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; begin select empno,ename,sal into ln_empno,ln_ename,ln_sal from emp where empno = &parameter1; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); end; /

10

Write a Simple plsql block to display employee name,number,salary, department name and location.

declare ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; begin select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where empno = &parameter1 and e.deptno = d.deptno; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); end; /

11

Write a simple plsql block to display maximum salary from the emp table. declare ln_sal emp.sal%type; begin select max(sal) into ln_sal from emp; dbms_output.put_line('The max sal is --'||ln_sal); end; /

12

Procedure: Create or replace procedure p_name(parameter1 datatype, parameter2 datatype) Is BEGIN NULL; END

Ex: create or replace procedure xx_max_sal is ln_sal emp.sal%type; begin select max(sal),deptno into ln_sal from emp; dbms_output.put_line('The max sal is --'||ln_sal); end; / Execution : begin xx_max_sal; end; / Exec xx_max_sal;

13

EX: Write a Simple proceudre to display employee name,number,salary, department name and location.

create or replace procedure xx_emp_dtls(p_empno number) is ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; begin select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where empno = p_empno and e.deptno = d.deptno; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); end; /

14

Exercise: Write a procedure to print the student information and their total marks and grade. show student marks,result,grade even if the student information doesnot exists by passing input parameter as sno and grade.

Write a procedure to print the student information and their total marks and grade. show student marks,result,grade even if the student information doesnot exists by passing input parameter as sno and result.

Write a procedure to print the student information and their total marks and grade. show student marks,result,grade even if the student information doesnot exists by passing input parameter as sno and marks. The student marks should be greater then marks parameter value.

15

EXCEPTIONS. Exception is an abnormal condition that causes the termination of the program in the middle of the execution.

Exception Handler: It is a unit of plsql code that oracle engine raised when an exception is occurred. When an exception is occurred,oracle engine identifies it and raises the exception to the exception handler which scans the plsql program for the occurrence of exception section and if found the exception handler then checks for the occurrence of the word when followed by a predefined or user defined exception,which inturn followed by a then keyword and action associated with that exception.

Exceptions are of 2 types: 1) Predefined exception. 2) User defined exception. these can be rasied explicitly by the user.

Some predefined exceptions examples: 1) Zero divide by Occurs when the divisor is zero. 2) No_data_found Occurs when the sql select statement fetching the records into variables retrieves no rows. 3) Too_many_rows Occurs when the sql select statement fetching the records into variables retrieves more then one row. 4) Others exception. Any other type exceptions rasied will be handled using this

16

NOTE: Exception should be always placed between begin and end block and exactly before the end.

Syntax: BEGIN --Any sql Statement. EXCEPTION WHEN Exception Name THEN Any action to be taken place (like printing a error message) END;

In the above syntax there can be many when exception clauses and if we use others exception clause then it should be placed at last always. If iam using no_data_found,too_many_rows and others exception then the seq should be always as per below example BEGIN --Any sql Statement. EXCEPTION WHEN NO_DATA_FOUND THEN Any action to be taken place (like printing a error message); WHEN TOO_MANY_ROWS THEN Any action to be taken place (like printing a error message); WHEN OTHERS THEN Any action to be taken place (like printing a error message); END;

17

But if I write in below way that will error. BEGIN --Any sql Statement. EXCEPTION WHEN NO_DATA_FOUND THEN Any action to be taken place (like printing a error message); WHEN OTHERS THEN Any action to be taken place (like printing a error message); WHEN TOO_MANY_ROWS THEN Any action to be taken place (like printing a error message); END;

BEGIN --Any sql Statement. EXCEPTION WHEN OTHERS THEN Any action to be taken place (like printing a error message); WHEN NO_DATA_FOUND THEN Any action to be taken place (like printing a error message); WHEN TOO_MANY_ROWS THEN Any action to be taken place (like printing a error message); END;

18

SQLERRM: Sql Error Message It is an oracle predefined keyword which holds oracle error message when any exception raises. Ex:1 create or replace procedure xx_emp_dtls(p_empno number) is ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; ln_flag char(1):= 'N'; begin BEGIN select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where empno = p_empno and e.deptno = d.deptno; exception when no_data_found then dbms_output.put_line('No data exists for the passed empno'||p_empno); when too_many_rows then dbms_output.put_line('too many rows for the passed'); when others then dbms_output.put_line('Others exception raised'||substr(sqlerrm,1,250)); END; dbms_output.put_line('The ename is --'||ln_ename);
19

dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); exception when others then dbms_output.put_line('Error in the xx_emp_dtls proceudre'||substr(sqlerrm,1,250)); end; / Ex2: create or replace procedure xx_emp_dtls(p_deptno number) is ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; ln_flag char(1):= 'N'; begin BEGIN select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where e.deptno = p_deptno and e.deptno = d.deptno; exception when no_data_found then dbms_output.put_line('No data exists for the passed empno'||p_deptno); when too_many_rows then dbms_output.put_line('too many rows for the passed');
20

when others then dbms_output.put_line('Others exception raised'||substr(sqlerrm,1,250)); END; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); exception when others then dbms_output.put_line('Error in the xx_emp_dtls proceudre'||substr(sqlerrm,1,250)); end; / create or replace procedure xx_emp_dtls(p_deptno number) is ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; ln_flag char(1):= 'N'; begin BEGIN select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where e.deptno = p_deptno and e.deptno = d.deptno; exception
21

when no_data_found then null; when others then dbms_output.put_line('Others exception raised'||substr(sqlerrm,1,250)); END; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); exception when others then dbms_output.put_line('Error in the xx_emp_dtls proceudre'||substr(sqlerrm,1,250)); end; / Print the no of records exists for the passed deptno and also print the employee dtls for the passed empno create or replace procedure xx_dtls(p_deptno dept.deptno%type ,p_empno emp.empno%type) is ln_cnt number; ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type

22

BEGIN select count(*) into ln_cnt from emp where deptno = p_deptno; dbms_output.put_line('The no of records is '||ln_cnt); -- printing the emp details BEGIN select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where e.empno = p_empno and e.deptno = d.deptno; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); exception when no_data_found then null; when others then dbms_output.put_line('Others exception raised'||substr(sqlerrm,1,250)); END; exception when others then dbms_output.put_line('Error in the xx_dtls procedure '||substr(sqlerrm,1,250)); END; /
23

Exercise: modify the written procedure by handling the exceptions in a right approach

Write a procedure to print the student information and their total marks and grade. show student marks,result,grade even if the student information doesnot exists by passing input parameter as sno and grade.

Write a procedure to print the student information and their total marks and grade. show student marks,result,grade even if the student information doesnot exists by passing input parameter as sno and result.

Write a procedure to print the student information and their total marks and grade. show student marks,result,grade even if the student information doesnot exists by passing input parameter as sno and marks. The student marks should be greater then marks parameter value.

User defined Exception: This is a exception which is declared in the declaration section by the user and rasie ir explicitly rasie keyword when ever we require..

Syntax: variable_name EXCEPTION.

24

Ex: create or replace procedure xx_dtls(p_deptno dept.deptno%type ,p_empno emp.empno%type) is ln_cnt number; ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; u_exp EXCEPTION; BEGIN select count(*) into ln_cnt from emp where deptno = p_deptno; dbms_output.put_line('The no of records is '||ln_cnt); if ln_cnt = 0 then raise u_exp; end if; -- printing the emp details BEGIN select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where e.empno = p_empno and e.deptno = d.deptno; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal);
25

dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); exception when no_data_found then null; when others then dbms_output.put_line('Others exception raised'||substr(sqlerrm,1,250)); END; exception when u_exp then dbms_output.put_line('user defined exception rasied'); when others then dbms_output.put_line('Error in the xx_dtls procedure '||substr(sqlerrm,1,250)); END; /

26

Write a procedure to print the no of records for the passed deptno and print emp dtails for the passes emp no. befire printing check if the flag value is Y. if it is other then Y or num or too many rows in the table then rasie user defined exception and print a appropriate message.

Create table ckh_tble(flag char(1));

create or replace procedure xx_dtls(p_deptno dept.deptno%type ,p_empno emp.empno%type) is ln_cnt number; ln_empno emp.empno%type; ln_ename emp.ename%type; ln_sal emp.sal%type; ln_dname dept.dname%type; ln_loc dept.loc%type; u_exp EXCEPTION; ln_flag char(1); BEGIN begin select nvl(flag,N) into ln_flag from chk_tble; exception when no_data_found then ln_flag := 'N' ; when others then ln_flag := 'N' ; end;
27

if ln_flag = 'N' then raise u_exp; end if; select count(*) into ln_cnt from emp where deptno = p_deptno; dbms_output.put_line('The no of records is '||ln_cnt); -- printing the emp details BEGIN select empno,ename,sal,dname,loc into ln_empno,ln_ename,ln_sal,ln_dname,ln_loc from emp e,dept d where e.empno = p_empno and e.deptno = d.deptno; dbms_output.put_line('The ename is --'||ln_ename); dbms_output.put_line('The sal is --'||ln_sal); dbms_output.put_line('The empno is --'||ln_empno); dbms_output.put_line('The dpartment name is --'||ln_dname); dbms_output.put_line('The location is --'||ln_loc); exception when no_data_found then null; when others then dbms_output.put_line('Others exception raised'||substr(sqlerrm,1,250)); END; exception when u_exp then dbms_output.put_line('user defined exception rasied please check the chk_tble');
28

when others then dbms_output.put_line('Error in the xx_dtls procedure '||substr(sqlerrm,1,250)); END; / Insert into table as value Y success for printing Insert into table as value Y,N etc multiple combinations raise exception Insert into table as value N raise exception Insert into table as value Null value. raise exception

29

Cursors. Cursors:

A cursor is a memory area in to which the rows of a select statement are loaded and processed.

Records Pointer: When a cursor is created oracle creates a pointer called record pointer that points to the current record among the set of the records in the cursor

Cursor attributes

A part from the creating a record pointer after the cursor is created oracle also creates some variables called cursor attributes which are used in knowing the status of the cursor like to know whether the cursor is open,close,found,not found

1)%Open = Return the status of the cursor

2)%Found = Determines whether any records exists of that select stmt assigned to the cursor

3)%NOT Found = Determines whether any records not exists of that select stmt assigned to the cursor

4)%ROWCOUNT = gives the no of rows in the cursor... ----------------------------------------------------------------------

30

There are 2 types of cursors

1) Implicit cursor: If the cursor is created by oracle then it is said to be Implicit Cursor The Name of the Implicit cursor is always be SQL

Plsql Block to demostrate Implicit cursor....

Ex1: Create or replace procedure p_upd_emp(p_deptno number) Is begin UPDATE EMP SET sal = sal+100 where deptno = p_deptno;

IF SQL%FOUND THEN dbms_output.put_line('Cursor found'); END IF;

IF SQL%NOTFOUND THEN dbms_output.put_line('Cursor not found '); END IF; exception when others then dbms_output.put_line('Error in the p_upd_emp procedure'||sqlerrm); End; ----------------------------------31

plsql block to demostrate to kow how many records got deleted or updated...

Create or replace procedure p_upd_emp(p_deptno number) Is begin UPDATE EMP SET sal = sal+100 where deptno = p_deptno; IF SQL%FOUND THEN dbms_output.put_line('Cursor found'); END IF; IF SQL%NOTFOUND THEN dbms_output.put_line('Cursor not found '); END IF; dbms_output.put_line('no of records updated are '||sql%rowcount); exception when others then dbms_output.put_line('Error in the p_upd_emp procedure'||sqlerrm); End; / -Create or replace procedure p_upd_emp(p_deptno number) Is ln_cnt number; begin UPDATE EMP
32

SET sal = sal+100 where deptno = p_deptno; IF SQL%FOUND THEN dbms_output.put_line('Cursor found'); END IF; IF SQL%NOTFOUND THEN dbms_output.put_line('Cursor not found '); END IF; ln_cnt:= sql%rowcount; dbms_output.put_line('no of records updated are '||ln_cnt); exception when others then dbms_output.put_line('Error in the p_upd_emp procedure'||sqlerrm); End; /

--------------------------------------------------------------------------------

2) Explicit cursor: If it is created by the programmer with the help of cursor keyword in the declaration sections , it is called explicit cursor...

The Name of the explicit cursor is user defined.....

Steps for creating the Explicit Cursor....

1) Declare the cursor in the declaration section via using the CURSOR Keyword...
33

Syntax: CURSOR CURSORNAME IS Select Statement;

Ex: Cursor c_emp is select * from emp;

When the above statement is executed then the pl/sql engine just makes a note of the cursor name(c_emp) with its associated select statement but doesnot associate memory for the o/p if the select statement.

Memory allocation is done only when the cursor is opened.

OIpen the cursor in the executable part...this is associated via the OPEN Keyword.

Syntax: Open cursor_name; Ex: Open C_emp;

When the above select statement is executed then the pl/sql engine executes the select statement associated with the cursor c_emp and then allocates memory for the output of the select statement.

Start the loop

Syntax :LOOP

34

Fetch the values of the current record from the cursor in to the variables which are already declared.

SYNTAX: Fetch Cursor name into var1,var2....

Ex: Fetch c_emp into v_empno,v_ename The Number of variables in the fetch stmt into clause must be same with the no of columns present in the cursor.... in terms of both datatype and size.

EXIT when the cursor finds no records left to be processed in the loop

End the loop and CLOSE the Cursor Ex: END LOOP; EX: Close c_emp;

After close of the cursor the records in the cursor memory is released. -----------------------------------------------

EX: Print the empname,sal,comm,job,dname,locations for those whose salary is greater then the min sal of the deptno 20; Create or replace procedure xx_emp_dtls(p_deptno number) is cursor c_emp is select e.ename ,e.sal -- ,nvl(e.comm,0) comm -- ,e.job -- ,d.dname
35

,d.loc from emp e ,dept d where d.deptno(+) = e.deptno and sal >(select min(sal) from emp where deptno = p_deptno); v_ename emp.ename%type; v_sal number; v_loc dept.loc%type; begin open c_emp; LOOP FETCH c_emp into v_ename,v_sal,v_loc; EXIT WHEN c_emp%notfound; dbms_output.put_line('ename'||v_ename); dbms_output.put_line('salary'||v_sal); dbms_output.put_line('location'||v_loc); END LOOP; -close c_emp; END xx_emp_dtls; /

EX: Print the empname,sal, locations by passing the deptno as parameter. If no records found for the given deptno value then print invalid deptno and if deptno is valid then print the emp details and if the deptno is passed as null then print the data for all the deptno satisfying the query.

36

Create or replace procedure xx_emp_dtls(p_deptno number) is cursor c_emp is select e.ename ,e.sal ,d.loc from emp e ,dept d where d.deptno(+) = e.deptno and e.deptno = nvl(p_deptno,e.deptno); v_ename emp.ename%type; v_sal number; v_loc dept.loc%type; ln_flag char(1):= 'N'; begin -open c_emp; LOOP FETCH c_emp into v_ename,v_sal,v_loc; EXIT WHEN c_emp%notfound; ln_flag:= 'Y'; dbms_output.put_line('emp detials are '||v_ename||'----'||v_sal||'----'||v_loc); END LOOP; -if ln_flag = 'N' then dbms_output.put_line('Invalid deptno passed '||p_deptno); end if; close c_emp; END xx_emp_dtls;
37

/ 2) write a plsql procedure to increase the salary of the employee of the emp table by 10% if job is manager 6% if job is clerk 5% is job is salesman 2% is any other. Pass deptno and empno as parameters and do the updation for all the records if the deptno and empno is passed as null and for the passed combination of deptno,empno values if there are no records in the query then print the message no data exists for the passed input values

Create or replace procedure xx_upate_sal(p_deptno number,p_empno number) is cursor c_emp is select ename,job,empno,sal from emp where deptno = nvl(p_deptno,deptno) and empno = nvl(p_empno,empno);

v_ename emp.ename%type; v_job emp.job%type; v_empno emp.empno%type; v_sal emp.sal%type; ln_flag char(1):= 'N'; begin open c_emp; LOOP FETCH c_emp into v_ename,v_job,v_empno,v_sal; EXIT WHEN c_emp%notfound; ln_flag:= 'Y';
38

dbms_output.put_line('old sal '||v_sal||' for empno '||v_empno); IF upper(v_job) = 'MANAGER' THEN UPDATE emp set sal = sal + (sal * 10/100) where empno = v_empno; ELSIF upper(v_job) = 'CLERK' THEN UPDATE emp set sal = sal + (sal * 6/100) where empno = v_empno; ELSIF upper(v_job) = 'SALESMAN' THEN UPDATE emp set sal = sal + (sal * 5/100) where empno = v_empno; ELSE UPDATE emp set sal = sal + (sal * 2/100) where empno = v_empno; END IF; END LOOP; close c_emp; COMMIT; if ln_flag = 'N' then dbms_output.put_line('Invalid input parameters'); end if; END; /

How to declare the cursor variable....

39

%ROWTYPE: It is used to assign the cursor records structure to a variable. Instead of fetching the values in to independent local variable we can dump them in to one local variable by declaring the variable with the data type as cursor%rowtype. --Execises:

write a plsql procedure to increase the salary of the employee of the emp table by 10% if job is manager 6% if job is clerk 5% is job is salesman 2% is any other. Pass deptno and empno as parameters and do the updation for all the records if the deptno and empno is passed as null and for the passed combination of deptno,empno values if there are no records in the query then print the message no data exists for the passed input values. Print the old salary and as well new updated salary laong with the employee name and job. Also include no of records getting printed.

EX: create or replace procedure xx_rk_sal(p_deptno number,p_empno number) is cursor c_emp is select ename,job,empno,sal from emp where deptno =nvl(p_deptno,deptno) and empno =nvl(p_empno,empno); ln_flag char(1):='N';
40

v_cnt number:=0; v_newsal number; r_emp c_emp%rowtype; begin open c_emp; LOOP FETCH c_emp into r_emp; EXIT WHEN c_emp%notfound; ln_flag:='y'; IF upper(r_emp.job)='MANAGER'THEN UPDATE emp SET sal=sal+(sal*10/100) WHERE empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*10/100); ELSIF upper(r_emp.job)='CLERK'THEN UPDATE emp set sal= sal+(sal*6/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*6/100); ELSIF upper(r_emp.job)='SALESMAN' THEN UPDATE emp set sal= sal+(sal*5/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*5/100); ELSE UPDATE emp set sal=sal+(sal*2/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*2/100);
41

end if; v_cnt:=v_cnt+sql%rowcount; dbms_output.put_line('old sal was '||r_emp.sal||'for empno is '||r_emp.empno||'and new salary is'||v_newsal); end loop; close c_emp; commit; dbms_output.put_line('No of rows updated = '||v_cnt); IF ln_flag ='N' then dbms_output.put_line('invalid input parameters'); end if; END; / write a plsql procedure to display all student marks,grade,name,sex,age details by passing sno as paramter. if the passed sno is invalid print the message as Invalid sno passed,if sno is passed as null print all the detials

-write a plsql procedure to display all transaction details by passing acctno as paramter. if the passed acctno is invalid or if there are no tansactions for the passed acctno then print the message as Invalid acctno or no transactions for the [passed account no...

42

Cursor For LOOP ------------------------

With the help of the cursor for loop the different steps of opening, fetching, closing of the cursor are automatic, also the memory variables are not required to store the cursor columns instead they are dumped in to the cursor variable as one unit which are individually accessed by giving the column name after the dot which is proceeded by the cursor variable name

Syntax: FOR C_varc in cursor_name loop End loop;

----------------------------------------------Ex: Write a plsql procedure to increase the salary of the employee of the emp table by 10% if job is manager 6% if job is clerk 5% is job is salesman 2% is any other. Pass deptno and empno as parameters and do the updation for all the records if the deptno and empno is passed as null and for the passed combination of deptno,empno values if there are no records in the query then print the message no data exists for the passes input values.
43

Exercise:

create or replace procedure xx_rk_sal(p_deptno number,p_empno number) is cursor c_emp is select ename,job,empno,sal from emp where deptno =nvl(p_deptno,deptno) and empno =nvl(p_empno,empno); ln_flag char(1):='N'; v_cnt number:=0; v_newsal number; r_emp c_emp%rowtype; begin

FOR r_emp in c_emp

LOOP

ln_flag:='Y';

IF upper(r_emp.job)='MANAGER'THEN UPDATE emp SET sal=sal+(sal*10/100) WHERE empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*10/100); ELSIF upper(r_emp.job)='CLERK'THEN UPDATE emp
44

set sal= sal+(sal*6/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*6/100); ELSIF upper(r_emp.job)='SALESMAN' THEN UPDATE emp set sal= sal+(sal*5/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*5/100); ELSE UPDATE emp set sal=sal+(sal*2/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*2/100); end if; v_cnt:=v_cnt+sql%rowcount; dbms_output.put_line('old sal was '||r_emp.sal||'for empno is '||r_emp.empno||'and new salary is'||v_newsal);

END LOOP;

commit; dbms_output.put_line('No of rows updated = '||v_cnt); IF ln_flag ='N' then dbms_output.put_line('invalid input parameters'); end if; END; /

----------------------------------------45

Write a plsql proceudre to increase the salary of the employee of the emp table by 10% if job is manager 6% if job is clerk 5% is job is salesman 2% is any other If no of records updated is more then that means the data will repeatedly updated which is wrong... whenever this happens donot do any updation just rollback everything...

create or replace procedure xx_rk_sal(p_deptno number,p_empno number) is ln_flag char(1):='N'; v_cnt number:=0; v_newsal number; u_exp exception; begin FOR r_emp in (select ename,job,empno,sal,deptno from emp where deptno =nvl(p_deptno,deptno) and empno =nvl(p_empno,empno)) LOOP ln_flag:='Y'; IF upper(r_emp.job)='MANAGER'THEN UPDATE emp SET sal=sal+(sal*10/100) WHERE empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*10/100); ELSIF upper(r_emp.job)='CLERK'THEN UPDATE emp
46

set sal= sal+(sal*6/100) where deptno = r_emp.deptno; v_newsal:=r_emp.sal+(r_emp.sal*6/100); ELSIF upper(r_emp.job)='SALESMAN' THEN UPDATE emp set sal= sal+(sal*5/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*5/100); ELSE UPDATE emp set sal=sal+(sal*2/100) where empno = r_emp.empno; v_newsal:=r_emp.sal+(r_emp.sal*2/100); end if; if sql%rowcount > 1 then raise u_exp; end if; v_cnt:=v_cnt+sql%rowcount; dbms_output.put_line('old sal was '||r_emp.sal||'for empno is '||r_emp.empno||'and new salary is'||v_newsal); END LOOP; commit; dbms_output.put_line('No of rows updated = '||v_cnt); IF ln_flag ='N' then dbms_output.put_line('invalid input parameters'); end if; exception when u_exp then rollback;
47

dbms_output.put_line('no of records updation is greater then 1, please contact IT suppprt team'); when others then dbms_output.put_line('Error in the main procedure '||sqlerrm); END; /

write a plsql procedure to increase the salary of the employee of the emp table by 10% passing the salgrade as the parameter.Print the emp names ,empno, old salary and new salary and no of records being updated.if the passed salgrade is invalid print the appropriate message. If the value of parameter is null then update all the records ------------------------------------------------------------------------

Parameterized cursors

Ex: print the dept name and the employees for those deptnames

create or replace procedure xx_dtls(p_deptno number) is cursor c_dept is select * from dept where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) is select * from emp where deptno = v_deptno; begin for r_dept in c_dept loop dbms_output.put_line('----------------------'); dbms_output.put_line(r_dept.dname);
48

for r_emp in c_emp(r_dept.deptno) loop dbms_output.put_line(r_emp.ename); end loop; end loop; exception when others then dbms_output.put_line('Error ins the xx_dtls procedure'); END; /

exception when others then dbms_output.put_line('Error ins the xx_dtls procedure'); END; /

----

Print the deptno details and then print the emp details for each deptno and no of employees working in that deptno.If no employees working for them then print it as no employees exists for that deptno. Take the deptno as parameter and if the value is passed as null then pick all deptno information and if the value passed is invalid then print as invalid deptno passed Print the subtotal salary for each deptno Print the total salary for all the deptnos

o/p :

49

----------------------Start of the report----------------------------------------------The Deptno is 10

The Department Name is Accounting The Location is Newyork

The ename is rakesh patel The empno is 1234 The salary is 1000 -----The ename is ankul The empno is 123 The salary is 1000

The total salary for deptno 10 is 2000 The total no of employees working in the deptno 10 is 2

The total salary for all deptnos is 10000 --------------------------End of the Report -------------------------------------------------

Output :

50

create or replace procedure dept_dtls(p_deptno number) is cursor c_dept is select * from dept_ank where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) /*Parameterised Cursor*/ is select * from emp_ank where deptno = v_deptno; /*Variables*/ dept_tot_sal number:=0; emp_cnt number:=0; tot_sal number:=0; v_flag number:=0; /*Execution Section*/ begin dbms_output.put_line('----------------------Start of the report-------------------------'); for r_dept in c_dept loop v_flag:=1; dept_tot_sal:=0; emp_cnt:=0; dbms_output.put_line('Department No is: '||r_dept.deptno); '||r_dept.dname); '||r_dept.loc);

dbms_output.put_line('Department Name is: dbms_output.put_line('Department Location is:

dbms_output.put_line('------------------------------------'); for r_emp in c_emp(r_dept.deptno)


51

loop dbms_output.put_line('Employee Number: '||r_emp.empno);

dbms_output.put_line('Employee Name: '||r_emp.ename); dbms_output.put_line('Salary: '||r_emp.sal);

dbms_output.put_line('---------------------------------'); dept_tot_sal:=dept_tot_sal+r_emp.sal; emp_cnt:=emp_cnt+1; end loop; if emp_cnt=0 then dbms_output.put_line('No employee working for department no' ||r_dept.deptno); else dbms_output.put_line('The total no of employees working in deptno'||r_dept.deptno|| ' is ' ||emp_cnt); dbms_output.put_line('The total salary for deptno'||r_dept.deptno|| ' is ' ||dept_tot_sal); end if; dbms_output.put_line('*****************************************************'); tot_sal:=tot_sal+dept_tot_sal; end loop; if v_flag=0 then dbms_output.put_line('Invalid department number. Please enter the valid department number.'); else dbms_output.put_line('The total salary of all the departments is ' ||tot_sal); end if; dbms_output.put_line('--------------------------End of the Report------------------------'); exception when others then dbms_output.put_line('Error ins the dept_dtls procedure'||sqlerrm); END;
52

Using a loop in a loop,. You can use either parameterized cursors or we can use below way as well

create or replace procedure dept_dtls(p_deptno number) is

/*Variables*/ dept_tot_sal number:=0; emp_cnt number:=0; tot_sal number:=0; v_flag number:=0; /*Execution Section*/ begin dbms_output.put_line('----------------------Start of the report-------------------------'); for r_dept in (select * from dept_ank where deptno = nvl(p_deptno,deptno)) loop v_flag:=1; dept_tot_sal:=0; emp_cnt:=0; dbms_output.put_line('Department No is: '||r_dept.deptno); '||r_dept.dname); '||r_dept.loc);

dbms_output.put_line('Department Name is: dbms_output.put_line('Department Location is:

dbms_output.put_line('------------------------------------'); for r_emp in (select * from emp_ank where deptno = r_dept.deptno)


53

loop dbms_output.put_line('Employee Number: '||r_emp.empno);

dbms_output.put_line('Employee Name: '||r_emp.ename); dbms_output.put_line('Salary: '||r_emp.sal);

dbms_output.put_line('---------------------------------'); dept_tot_sal:=dept_tot_sal+r_emp.sal; emp_cnt:=emp_cnt+1; end loop; if emp_cnt=0 then dbms_output.put_line('No employee working for department no' ||r_dept.deptno); else dbms_output.put_line('The total no of employees working in deptno'||r_dept.deptno|| ' is ' ||emp_cnt); dbms_output.put_line('The total salary for deptno'||r_dept.deptno|| ' is ' ||dept_tot_sal); end if; dbms_output.put_line('*****************************************************'); tot_sal:=tot_sal+dept_tot_sal; end loop; if v_flag=0 then dbms_output.put_line('Invalid department number. Please enter the valid department number.'); else dbms_output.put_line('The total salary of all the departments is ' ||tot_sal); end if; dbms_output.put_line('--------------------------End of the Report------------------------'); exception when others then dbms_output.put_line('Error ins the dept_dtls procedure'||sqlerrm); END;
54

/ --Ex: ----------------------------2)Print the account details and print the transaction details for each accno and no of transactions takes palce for each accno. Pass the accno as parameter and if the accno parameter value is passed as null then print for all accnos else if it is passed and if that accno is invalid then print the appro[riate message as invalid parameter value.

Different modes of parameters:

IN : The default parameter is IN. the value should be passed in to procedure mandatory. OUT: Need to pass some variable where using out mode we can fetch the value from the procedure INOUT: Pass the input values and assign some other value in the procedure and print it outside the procedure by fetching it in to variable.

create or replace procedure p_dept_dtls(p_deptno number,p_count out number) is cursor c_emp is select * from emp where deptno=nvl(p_deptno,deptno); ln_flag char(1):= 'N'; ln_cnt number:= 0; begin for r_emp in c_emp
55

loop ln_flag := 'Y'; ln_cnt := ln_cnt+1; dbms_output.put_line('ename is '||r_emp.ename); end loop; if ln_flag = 'N' then dbms_output.put_line('No data exists for the deptno'); end if; p_count :=ln_cnt; exception when others then dbms_output.put_line('error in the procedure '||sqlerrm); end; /

declare ln_count number:=0; begin p_dept_dtls(20,ln_count); dbms_output.put_line('the count is '||ln_count); end; / create or replace procedure p_emp_out(p_empno number ,p_ename out varchar2 ,p_sal out number) is BEGIN BEGIN
56

select ename,sal into p_ename,p_sal from emp where empno = p_empno; EXCEPTION WHEN NO_DATA_FOUND THEN p_ename := null; p_sal := null; WHEN OTHERS THEN dbms_output.put_line('Error in the select statement'||SQLERRM); END;

EXCEPTION WHEN OTHERS THEN dbms_output.put_line('Error in the main proceudre'||SQLERRM); END p_emp_out;

declare ln_ename emp.ename%type; ln_sal emp.sal%type; begin p_emp_out(7369,ln_ename,ln_sal); dbms_output.put_line('Ename is -->'||ln_ename); dbms_output.put_line('Salary is -->'||ln_sal); end;

57

Inout example --------------------------create or replace procedure p_emp_out(p_empno in out number ,p_ename out varchar2 ,p_sal out number) is BEGIN BEGIN select ename,sal into p_ename,p_sal from emp where empno = p_empno; p_empno := 9999; EXCEPTION WHEN NO_DATA_FOUND THEN p_empno := 0000; p_ename := null; p_sal := null; WHEN OTHERS THEN dbms_output.put_line('Error in the select statement'||SQLERRM); END; EXCEPTION WHEN OTHERS THEN dbms_output.put_line('Error in the main proceudre'||SQLERRM); END p_emp_out;

declare ln_ename emp.ename%type;


58

ln_sal emp.sal%type; ln_empno number := 7369; begin p_emp_out(ln_empno,ln_ename,ln_sal); dbms_output.put_line('Ename is -->'||ln_ename); dbms_output.put_line('Salary is -->'||ln_sal); dbms_output.put_line('empno -->'||ln_empno); end;

Procedures or functions: It is a collection of sql and plsql blocks of codes used to prevent the representation of coding by making it occur only one time.

Procedures or functions are stored n the database.

When a call to procedure or functions is made in the database server it loads the current procedures or functions in to the memory which respond to many requests of the same requirements.

SYNTAX: CREATE OR REPLACE PROCEDURE PROCEDURE_NAME(PARAMETERS) IS --DECLARE ANY VARIBES,CURSORS ETC. BEGIN --ANY ACTION TO BE DONE IN EXECUTABLE SECTION. EXCEPTION SECTION END PROCEDURE NAME;

59

SYNTAX: CREATE OR REPLACE FUNCTION FUNCTION_NAME(PARAMETERS) RETURN DATATYPE IS --DECLARE ANY VARIBES,CUSRSORS ETC. BEGIN --ANY ACTION TO BE DONE IN EXECUTABLE SECTION. RETURN VALUE; EXCEPTION SECTION END FUCNTION_NAME; Ex: write a function to accept dept no as parameter and return the department name. Create or replace function xx_dept_1(p_deptno number) Return varchar2 Is --declaration variables ln_dname dept.dname%type; Begin Select dname Into ln_dname From dept Where deptno = p_deptno; Return ln_dname; Exception When no_data_found then Return null; Dbms_output.put_line(No data found); When others then Return null; Dbms_output.put_line(Error in the xx_dept function||sqlerrm);
60

End xx_dept_1;

Execution of a functions:

Method1: select xx_dept_1(10) from dual;

Method2: declare Ln_val varchar2(100); Begin Ln_val := xx_dept_1(0); Dbms_output.put_line(ln_val); End; 9652203300

1) Write a function to print grade of the employee by passing empno. 2) Write a function to print the ename of the employee by passing empno. 3) Write a function to print the student grade by passing std no. 4) Write a function to print the sum of salaries for the passed deptno parameter. 5) Write as function to print the salary by deducting 7.65% from that salary by passing emp no. 6) Write a function to print the 3 highest paid employee name no parameters to be passed. 7) Write a function to print the total deposited amount from the trx_table by passing accno.

Packages: They are nothing but clubbing of functions, procedures as one unit. It consists of 2 parts:
61

1) Package Specification: In this section we declare the functions, procedures etc. 2) Package Body: We write the procedure, functions body which is declared in the package specification.

Note: when the procedure or functions are declared in the package specification, their body must be written in the package body.

Syntax: Create or replace package Package_name Is Begin Procedure p1(parameters); Function f1(parameters) return number; Procedure p2(parameters); End;

Create or replace package body package_name Is Procedure p1(parameters) Is Begin -----action; End p1; --Procedure p2(parameters) Is Begin
62

-----action; End p2; fucntion f1(parameters) Is Begin -----action; End f1; End package_name;

---------------------------------------------------EX1:

CREATE OR REPLACE PACKAGE XX_EMP_PKG IS PROCEDURE P_EMP_DTLS(P_DEPTNO NUMBER); FUNCTION F_SALGRADE(P_EMPNO NUMBER) RETURN VARCHAR2;

PROCEDURE P_OUTPUT(P_STRING VARCHAR2); END XX_EMP_PKG;

CREATE OR REPLACE PACKAGE BODY XX_EMP_PKG IS FUNCTION F_SALGRADE(P_EMPNO NUMBER) RETURN VARCHAR2 is v_grade salgrade_ank.grade%type; begin

select grade into v_grade


63

from salgrade_ank sg, emp_ank e where e.empno = p_empno and e.sal between sg.lowsal and sg.highsal; return v_grade;

exception when no_data_found then return null; P_OUTPUT ('No data found'); when others then return null; P_OUTPUT ('Error in the F_SALGRADE function'||sqlerrm); end F_SALGRADE; -PROCEDURE P_EMP_DTLS(P_DEPTNO NUMBER) IS cursor c_dept is select * from dept_ank where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) /*Parameterised Cursor*/ is select * from emp_ank where deptno = v_deptno;

/*Variables*/ dept_tot_sal number:=0; emp_cnt number:=0; tot_sal number:=0; v_flag number:=0;

/*Execution Section*/ begin

64

P_OUTPUT ('----------------------Start of the report-------------------------'); P_OUTPUT ('----------------------Start of the report-------------------------');

for r_dept in c_dept loop v_flag:=1; dept_tot_sal:=0; emp_cnt:=0; P_OUTPUT ('Department No is: '||r_dept.deptno); P_OUTPUT ('Department Name is: '||r_dept.dname); P_OUTPUT ('Department Location is: '||r_dept.loc); P_OUTPUT ('------------------------------------');

for r_emp in c_emp(r_dept.deptno) loop P_OUTPUT ('Employee Number: '||r_emp.empno); P_OUTPUT ('Employee Name: '||r_emp.ename); P_OUTPUT ('Salary: '||r_emp.sal); P_OUTPUT ('------'); dept_tot_sal:=dept_tot_sal+r_emp.sal; emp_cnt:=emp_cnt+1; end loop; if emp_cnt=0 then P_OUTPUT ('No employee working for department no' ||r_dept.deptno); else P_OUTPUT ('The total no of employees working in deptno'||r_dept.deptno|| ' is ' ||emp_cnt); end if; P_OUTPUT ('The total salary for deptno'||r_dept.deptno|| ' is ' ||dept_tot_sal); P_OUTPUT ('*****************************************************');
65

tot_sal:=tot_sal+dept_tot_sal;

end loop;

if v_flag=0 then P_OUTPUT ('Invalid department number. Please enter the valid department number.'); end if;

if v_flag=1 and p_deptno is null then P_OUTPUT ('The total salary of all the departments is ' ||tot_sal); end if;

P_OUTPUT('--------------------------End of the Report------------------------');

exception when others then P_OUTPUT('Error in the P_EMP_DTLS procedure'||SQLERRM); END P_EMP_DTLS; -PROCEDURE P_OUTPUT(P_STRING VARCHAR2) IS BEGIN DBMS_OUTPUT.PUT_LINE(P_STRING); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(ERROR IN THE P_OUTPUT PROCEDURE||SQLERRM);
66

END P_OUTPUT; ---

END XX_EMP_PKG;

---------------------------------------------------EX2: MAKING P_OUTPUT PROCEDURE AS PRVATE PROCEDURE..

CREATE OR REPLACE PACKAGE XX_EMP_PKG IS PROCEDURE P_EMP_DTLS(P_DEPTNO NUMBER); FUNCTION F_SALGRADE(P_EMPNO NUMBER) RETURN VARCHAR2;

END XX_EMP_PKG;

CREATE OR REPLACE PACKAGE BODY XX_EMP_PKG IS -PROCEDURE P_OUTPUT(P_STRING VARCHAR2) IS BEGIN DBMS_OUTPUT.PUT_LINE(P_STRING); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(ERROR IN THE P_OUTPUT PROCEDURE||SQLERRM); END P_OUTPUT; ---

67

FUNCTION F_SALGRADE(P_EMPNO NUMBER) RETURN VARCHAR2 is v_grade salgrade_ank.grade%type; begin

select grade into v_grade from salgrade_ank sg, emp_ank e where e.empno = p_empno and e.sal between sg.lowsal and sg.highsal; return v_grade;

exception when no_data_found then return null; P_OUTPUT ('No data found'); when others then return null; P_OUTPUT ('Error in the F_SALGRADE function'||sqlerrm); end F_SALGRADE; -PROCEDURE P_EMP_DTLS(P_DEPTNO NUMBER) IS cursor c_dept is select * from dept_ank where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) /*Parameterised Cursor*/ is select * from emp_ank where deptno = v_deptno;

/*Variables*/
68

dept_tot_sal number:=0; emp_cnt number:=0; tot_sal number:=0; v_flag number:=0;

/*Execution Section*/ begin

P_OUTPUT ('----------------------Start of the report-------------------------'); P_OUTPUT ('----------------------Start of the report-------------------------');

for r_dept in c_dept loop v_flag:=1; dept_tot_sal:=0; emp_cnt:=0; P_OUTPUT ('Department No is: '||r_dept.deptno); P_OUTPUT ('Department Name is: '||r_dept.dname); P_OUTPUT ('Department Location is: '||r_dept.loc); P_OUTPUT ('------------------------------------');

for r_emp in c_emp(r_dept.deptno) loop P_OUTPUT ('Employee Number: '||r_emp.empno); P_OUTPUT ('Employee Name: '||r_emp.ename); P_OUTPUT ('Salary: '||r_emp.sal); P_OUTPUT ('------'); dept_tot_sal:=dept_tot_sal+r_emp.sal; emp_cnt:=emp_cnt+1;
69

end loop; if emp_cnt=0 then P_OUTPUT ('No employee working for department no' ||r_dept.deptno); else P_OUTPUT ('The total no of employees working in deptno'||r_dept.deptno|| ' is ' ||emp_cnt); end if; P_OUTPUT ('The total salary for deptno'||r_dept.deptno|| ' is ' ||dept_tot_sal); P_OUTPUT ('*****************************************************');

tot_sal:=tot_sal+dept_tot_sal;

end loop;

if v_flag=0 then P_OUTPUT ('Invalid department number. Please enter the valid department number.'); end if;

if v_flag=1 and p_deptno is null then P_OUTPUT ('The total salary of all the departments is ' ||tot_sal); end if;

P_OUTPUT('--------------------------End of the Report------------------------');

exception when others then P_OUTPUT('Error in the P_EMP_DTLS procedure'||SQLERRM); END P_EMP_DTLS; -70

END XX_EMP_PKG;

EX2: USING FUNCTION IN A PROCEDURE

CREATE OR REPLACE PACKAGE XX_EMP_PKG IS PROCEDURE P_EMP_DTLS(P_DEPTNO NUMBER); END XX_EMP_PKG;

CREATE OR REPLACE PACKAGE BODY XX_EMP_PKG IS -PROCEDURE P_OUTPUT(P_STRING VARCHAR2) IS BEGIN DBMS_OUTPUT.PUT_LINE(P_STRING); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(ERROR IN THE P_OUTPUT PROCEDURE||SQLERRM); END P_OUTPUT; --procedure p_emp_out(p_empno number ,p_ename out varchar2 ,p_sal out number) is BEGIN BEGIN
71

select ename,sal into p_ename,p_sal from emp where empno = p_empno; EXCEPTION WHEN NO_DATA_FOUND THEN p_ename := null; p_sal := null; WHEN OTHERS THEN P_OUTPUT('Error in the select statement'||SQLERRM); END;

EXCEPTION WHEN OTHERS THEN P_OUTPUT('Error in the main proceudre'||SQLERRM); END p_emp_out;

--FUNCTION F_SALGRADE(P_EMPNO NUMBER) RETURN VARCHAR2 is v_grade salgrade_ank.grade%type; begin

select grade into v_grade from salgrade_ank sg, emp_ank e where e.empno = p_empno and e.sal between sg.lowsal and sg.highsal;
72

return v_grade;

exception when no_data_found then return null; P_OUTPUT ('No data found'); when others then return null; P_OUTPUT ('Error in the F_SALGRADE function'||sqlerrm); end F_SALGRADE; -PROCEDURE P_EMP_DTLS(P_DEPTNO NUMBER) IS cursor c_dept is select * from dept_ank where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) /*Parameterised Cursor*/ is select * from emp_ank where deptno = v_deptno;

/*Variables*/ dept_tot_sal number:=0; emp_cnt number:=0; tot_sal number:=0; v_flag number:=0; LN_GRADE VARCHAR2(1); LN_ENAME EMP.ENAME%TYPE; LN_SAL EMP.SAL%TYPE;

/*Execution Section*/ begin

73

P_OUTPUT ('----------------------Start of the report-------------------------'); P_OUTPUT ('----------------------Start of the report-------------------------');

for r_dept in c_dept loop v_flag:=1; dept_tot_sal:=0; emp_cnt:=0; P_OUTPUT ('Department No is: '||r_dept.deptno); P_OUTPUT ('Department Name is: '||r_dept.dname); P_OUTPUT ('Department Location is: '||r_dept.loc); P_OUTPUT ('------------------------------------');

for r_emp in c_emp(r_dept.deptno) loop --CALLING THE FUNCTION INORDER TO FETCH THE SALGRADE OF A EMPLOYEE LN_GRADE := F_SALGRADE(r_emp.empno); --CALLING THE PROCEDURE TO FETCH DETIALS. p_emp_out(r_emp.empno,LN_ENAME,LN_SAL); P_OUTPUT ('TEST PROVATE PROC Employee NAME: '|| LN_ENAME); P_OUTPUT ('TEST PROVATE PROC SAL: '|| LN_SAL); P_OUTPUT ('Employee Number: '||r_emp.empno); P_OUTPUT ('Employee Name: '||r_emp.ename); P_OUTPUT ('Salary: '||r_emp.sal); P_OUTPUT (SALGRADE IS : '|| LN_GRADE); P_OUTPUT ('------'); dept_tot_sal:=dept_tot_sal+r_emp.sal; emp_cnt:=emp_cnt+1;
74

LN_GRADE := NULL; end loop; if emp_cnt=0 then P_OUTPUT ('No employee working for department no' ||r_dept.deptno); else P_OUTPUT ('The total no of employees working in deptno'||r_dept.deptno|| ' is ' ||emp_cnt); end if; P_OUTPUT ('The total salary for deptno'||r_dept.deptno|| ' is ' ||dept_tot_sal); P_OUTPUT ('*****************************************************');

tot_sal:=tot_sal+dept_tot_sal;

end loop;

if v_flag=0 then P_OUTPUT ('Invalid department number. Please enter the valid department number.'); end if;

if v_flag=1 and p_deptno is null then P_OUTPUT ('The total salary of all the departments is ' ||tot_sal); end if; P_OUTPUT('--------------------------End of the Report------------------------'); exception when others then P_OUTPUT('Error in the P_EMP_DTLS procedure'||SQLERRM); END P_EMP_DTLS; --

END XX_EMP_PKG;
75

1)Difference between function,procedure and package. 2) what are collections.what are collection attributes. 3) what is difference between record type and table type. 4) what is bulk binding? 5) Difference between bulk collect and forall 5) What is ref cursor? 6) What is execute immediate?

1) Difference between function, procedure and package. Package-->It stores and compiles all the functions and procedures declared in SGA(System Global Area).Whenever stored procedures or functions are called from this package,it will get them from SGA.So it perfomance is definetly high.

Procedures-->( perform an action):They are subprograms which perform certain action.They cannot be called from select statement.

Functions-->( Function used to compute a value and return a value ) :They are subprograms which return a value.They can be used in select statement and also its return value can be assigned to a variable.

76

procedure 1>procedure is used for performing action

function 1> its used for computing value and returning value

2> procedure may or maynot return value

2> function must and should return value

3>it cant be used inside sql statement

3>it can be called inside sql statement

4> its cant be called as part of expression

4>its always called as part of expression

Package is faster when you working on specific project and all your functions and procedure are in that package. because package load into memory and remain in memory till the place available so execution is fast. for calling realted procedure, function and global variable.

but if you have a small and misc work. then you should use single function or procedure it will take a small memory and load fast

2) what are collections. what are collection attributes.? A collection is an ordered group of elements, all of the same type. It is a general concept that encompasses lists, arrays, and other familiar data types. Each element has a unique subscript that determines its position in the collection.

77

collections can have only one dimension, you can model multi-dimensional arrays by creating collections whose elements are also collections. *To use collections in an application, you define one or more PL/SQL types, then define variables of those types. You can define collection types in a procedure, function, or package. You can pass collection variables as parameters, to move data between client-side applications and stored subprograms. To look up data that is more complex than single values, you can store PL/SQL records or SQL object types in collections. Nested tables and varrays can also be attributes of object types. *(REFERENCE FROM http://docs.oracle.com/cd/B10500_01) USED IN THIS ANSWER BY RAKESH PATEL.)

PL/SQL offers these collection types:

Index-by tables, also known as associative arrays, let you look up elements using arbitrary numbers and strings for subscript values. (They are similar to hash tables in other programming languages.)

Nested tables hold an arbitrary number of elements. They use sequential numbers as subscripts. You can define equivalent SQL types, allowing nested tables to be stored in database tables and manipulated through SQL.

Varrays (short for variable-size arrays) hold a fixed number of elements (although you can change the number of elements at runtime). They use sequential numbers as subscripts. You can define equivalent SQL types, allowing varrays to be stored in database tables. They can be stored and retrieved through SQL, but with less flexibility than nested tables.

78

Collection attribute: Table_type.first Table_type.last Table_type.count Table_type.delete

3) what is difference between record type and table type.

Record Type: This is a user defined data type that groups a bunch of fields together into a single structure. In C the reserved word struct is used to define this.

EX: type t_rec is record(empno emp.empno%type ,dname dept.dname%type ,ename emp.ename%type; ,loc dept.loc%type ,message varchar2(1000));

Table type: is better and more accurately known as a collection or an array. an array is typically a list of records ("standard variables"). A collection is typically a list of objects ("object variables/pointers")

Ex: type t1 is table of emp.empno%type index by binary_integer;

type t1 is table of VARCHAR2(100) index by binary_integer;

type t1 is table of emp%rowtype index by binary_integer;

type t1 is table of cursor%rowtype index by binary_integer;

79

4) what is bulk binding? "bulk binds" was added to PL/SQL back in Oracle 8i. Bulk binds enable a PL/SQL program to fetch many rows from a cursor in one call instead of fetching one row at a time. Bulk binds also allow many similar DML statements to be executed with one call instead of requiring a separate call for each. For certain types of PL/SQL programs, using bulk binds will reduce CPU usage and make the code run faster. A context switch occurs every time the PL/SQL engine calls the SQL engine to parse, execute, or fetch from a cursor. Since context switches use CPU time, reducing the number of context switches will reduce the amount of CPU time used. In addition, the SQL engine can often reduce the number of logical reads required when multiple rows are fetched in one call. Reducing logical reads also saves CPU time.

Using bulk binding we can reduce the context switched between sql and plsql engines *(REFERENCE FROM http://www.dbspecialists.com/files/presentations/bulk_binds.html USED IN THIS ANSWER BY RAKESH PATEL.)

5) Difference between bulk collect and forall Using bulk collect we can fetch the records at once from the sql engine. Bulk Collect is for quickly loading a cursor generally into a table type variable within a procedure.

80

ex. Fetch curs BULK_COLLECT into table_var LIMIT 200;

FORALL is for processing the table variable once it is loaded. FORALL is much faster than looping through a table index. ex.

FORALL j in t_tbl.first..t_tbl.last insert into some_table values t_tbl(j);

This is much faster than:

For j in t_tbl.first..t_tbl.last loop insert into some_table values t_tbl(j); end loop;

NOTE: FORALL statement is limited to performing one and only one DML statement. *(REFERENCE FROM http://dba-blog.blogspot.com/2005/08/using-of-bulk-collect-andforall-for.htmlUSED IN THIS ANSWER BY RAKESH PATEL.)

81

Ex: create or replace procedure xx_emp_dtls(p_deptno number) is cursor c_emp is select empno,ename,sal from emp where deptno = nvl(p_deptno,deptno); type t_emp is table of c_emp%rowtype index by binary_integer; r_emp t_emp; begin open c_emp; fetch c_emp bulk collect into r_emp; close c_emp; for i in 1..r_emp.count loop dbms_output.put_line('ename'||r_emp(i).ename);

for r_dept in (select dname from dept where deptno = r_emp(i).deptno) loop dbms_output.put_line('dname is '||r_dept.dname); end loop;

end loop; exception when others then dbms_output.put_line('Error in the main procedure'||sqlerrm); End xx_emp_dtls;
82

create or replace procedure xx_emp_dtls(p_deptno number) is cursor c_dept is select dname,loc,deptno from dept where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) is select empno,ename,sal from emp where deptno = v_deptno; type t_dept is table of c_dept%rowtype index by binary_integer; r_dept t_dept; type t_emp is table of c_emp%rowtype index by binary_integer; r_emp t_emp; begin open c_dept; fetch c_dept bulk collect into r_dept; close c_dept; for i in 1..r_dept.count loop dbms_output.put_line('dname is '||r_dept(i).dname); open c_emp(r_dept(i).deptno); fetch c_emp bulk collect into r_emp; close c_emp; for j in 1.. r_emp.count loop dbms_output.put_line('ename'||r_emp(j).ename);
83

end loop;

r_emp.delete;

end loop; exception when others then dbms_output.put_line('Error in the main procedure'||sqlerrm); End xx_emp_dtls; /

create or replace procedure xx_emp_dtls(p_deptno number) is cursor c_dept is select deptno,dname,loc from dept where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) is select empno,ename,sal from emp where deptno = v_deptno; type t_dept is table of c_dept%rowtype index by binary_integer; r_dept t_dept; type t_emp is table of c_emp%rowtype index by binary_integer; r_emp t_emp; begin open c_dept; fetch c_dept bulk collect into r_dept; close c_dept;
84

for i in 1..r_dept.count loop dbms_output.put_line('dname is '||r_dept(i).dname); open c_emp(r_dept(i).deptno); fetch c_emp bulk collect into r_emp; close c_emp; for j in 1.. r_emp.count loop dbms_output.put_line('ename'||r_emp(j).ename); end loop; r_emp.delete; end loop; FORALL i in 1..r_dept.count insert into xx_dept_test values r_dept(i); exception when others then dbms_output.put_line('Error in the main procedure'||sqlerrm); End xx_emp_dtls; /

create or replace procedure xx_emp_dtls(p_deptno number) is cursor c_dept is select deptno,dname,loc from dept where deptno = nvl(p_deptno,deptno); cursor c_emp(v_deptno number) is select empno,ename,sal from emp
85

where deptno = v_deptno; type t_dept is table of c_dept%rowtype index by binary_integer; r_dept t_dept; type t_emp is table of c_emp%rowtype index by binary_integer; r_emp t_emp; begin open c_dept; fetch c_dept bulk collect into r_dept; close c_dept; for i in 1..r_dept.count loop dbms_output.put_line('dname is '||r_dept(i).dname); open c_emp(r_dept(i).deptno); fetch c_emp bulk collect into r_emp; close c_emp; for j in 1.. r_emp.count loop dbms_output.put_line('ename'||r_emp(j).ename); end loop; r_emp.delete; end loop; FORALL i in 1..r_dept.count -- insert into xx_dept_test values r_dept(i); insert into (select deptno,dname,loc from x_dept_test1) values r_dept(i); exception when others then dbms_output.put_line('Error in the main procedure'||sqlerrm); End xx_emp_dtls;
86

6) What is ref cursor?

A ref cursor in Oracle PL/SQL is much like an ordinary PL/SQL cursor in that it acts as a pointer to the result set of the cursor with which it is associated. However, the difference is that a ref cursor can be assigned to different result sets whereas a cursor is always associated with the same result set. Cursors and ref cursors are not interchangeable.

The real purpose of ref cursors is to be able to share cursors and result sets between the client and the Oracle server or between different subroutines. For example you might open a cursor in an Oracle Forms client and then continue working with the cursor on the server or you might open a cursor in say a Java program and then continue working with it in a PL/SQL stored procedure.

Ref cursors also come in two variants: strongly typed and weakly typed depending on how likely you are (or want to) reuse a cursor variable. Weak ref cursor types can be associated with any query whereas strong ref cursor types can only be associated with cursors of the same type.

Ex: CREATE OR REPLACE procedure emp_dtls_dynamic(p_flag IN varchar2) is type t_rec is RECORD (empno emp.empno%type ,ename emp.ename%type ,sal emp.sal%type ,comm emp.comm%type ,dname dept.dname%type); type t1 is table of t_rec index by binary_integer;
87

r1 t1; type t_ref is REF CURSOR; r_ref begin IF p_flag = 'Y' then OPEN r_ref for select empno,ename,sal,nvl(comm,100),dname from emp e,dept d where e.deptno = d.deptno and sal <= 5000; ELSE OPEN r_ref for select empno,ename,sal,nvl(comm,110),dname from emp e,dept d where e.deptno = d.deptno and sal > 5000; END IF; FETCH r_ref bulk collect into r1; close r_ref; FOR I in 1..r1.count LOOP DBMS_OUTPUT.PUT_LINE('Ename -->'||r1(i).ename); DBMS_OUTPUT.PUT_LINE('salary -->'||r1(i).sal); DBMS_OUTPUT.PUT_LINE('dname -->'||r1(i).dname); DBMS_OUTPUT.PUT_LINE('comm -->'||r1(i).comm); END LOOP; exception when others then DBMS_OUTPUT.PUT_LINE('Error ocured in procedure'||SQLERRM); END ; /
88

t_ref;

7) What is execute immediate?

The EXECUTE IMMEDIATE statement executes a dynamic SQL statement or anonymous PL/SQL block. You can use it to issue SQL statements that cannot be represented directly in PL/SQL, or to build up statements where you do not know all the table names, WHERE clauses, and so on in advance. CREATE OR REPLACE procedure emp_dtls_dynamic(p_flag IN varchar2) is type t_rec is RECORD (empno emp.empno%type ,ename emp.ename%type ,sal emp.sal%type ,comm emp.comm%type ,dname dept.dname%type); type t1 is table of t_rec index by binary_integer; r1 t1; type t_ref is REF CURSOR; r_ref t_ref;

ln_flag char(1):='N'; begin IF p_flag = 'Y' then OPEN r_ref for select empno,ename,sal,nvl(comm,100),dname from emp e,dept d where e.deptno = d.deptno and sal <= 2000; ELSE OPEN r_ref for select empno,ename,sal,nvl(comm,110),dname from emp e,dept d where e.deptno = d.deptno
89

and sal > 2000; END IF; FETCH r_ref bulk collect into r1; close r_ref; FOR I in 1..r1.count LOOP ln_flag := 'Y'; DBMS_OUTPUT.PUT_LINE('Ename -->'||r1(i).ename); DBMS_OUTPUT.PUT_LINE('salary -->'||r1(i).sal); DBMS_OUTPUT.PUT_LINE('dname -->'||r1(i).dname); DBMS_OUTPUT.PUT_LINE('comm -->'||r1(i).comm); END LOOP; if ln_flag = 'Y' then execute immediate 'truncate table emp_backup1'; else dbms_output.put_line('No data found'); end if; FORALL i in 1..r1.count insert into emp_backup1 values r1(i); commit; exception when others then DBMS_OUTPUT.PUT_LINE('Error ocured in procedure'||SQLERRM); END ; /

90

CREATE OR REPLACE procedure emp_dtls_dynamic(p_deptno number,p_flag IN varchar2) is type t_rec is RECORD (empno emp.empno%type ,ename emp.ename%type ,sal emp.sal%type ,comm emp.comm%type ,dname dept.dname%type); type t1 is table of t_rec index by binary_integer; r1 t1; type t_ref is REF CURSOR; r_ref t_ref;

ln_flag char(1):='N'; v_sql varchar2(32000); begin IF p_flag = 'Y' then v_sql := 'select empno,ename,sal,nvl(comm,100),dname from emp e,dept d where e.deptno = d.deptno and sal <= 2000 and e.deptno = nvl(:1,e.deptno)'; ELSE v_sql := 'select empno,ename,sal,nvl(comm,100),dname from emp e,dept d where e.deptno = d.deptno and sal <= 2000 and e.deptno = nvl(:1,e.deptno)'; END IF;
91

execute immediate v_sql bulk collect into r1 using p_deptno ; FOR I in 1..r1.count LOOP ln_flag := 'Y'; DBMS_OUTPUT.PUT_LINE('Ename -->'||r1(i).ename); DBMS_OUTPUT.PUT_LINE('salary -->'||r1(i).sal); DBMS_OUTPUT.PUT_LINE('dname -->'||r1(i).dname); DBMS_OUTPUT.PUT_LINE('comm -->'||r1(i).comm); END LOOP; if ln_flag = 'Y' then execute immediate 'truncate table emp_backup1'; else dbms_output.put_line('No data found'); end if; FORALL i in 1..r1.count insert into emp_backup1 values r1(i); commit; exception when others then DBMS_OUTPUT.PUT_LINE('Error ocured in procedure'||SQLERRM); END ; / *(REFERENCE FROM http://docs.oracle.com/cd/B10500_01) USED IN THIS ANSWER BY RAKESH PATEL.)

92

Potrebbero piacerti anche