0% found this document useful (0 votes)
70 views

Oracle Notes

Uploaded by

raghava.dsk
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
70 views

Oracle Notes

Uploaded by

raghava.dsk
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 588

ORACLE(Relational Database)

SQL PL/SQL

SQL -> Structured Query Language

-> It is a Non-Procedural Language ( If any language not supported


control structures and Iteration control statements )

->

PL/SQL -> Programming / Procedural Language ( If any language supported


control structures and Iteration control statements )

'c' - lang.

DB FUNDAMENTALS :
-----------------

-> What is a Database ?

-> Where we can store the data permanently that location name is
called as DATABASE

BANK DB ( SERVER )
.
.
.
.
100000

What is need of databases ?

-> Databases are used for to purposes in applications

i. OLTP(OnLineTransaction Processing) purpose :

-> Databases data is used for our day-to-day


activities

ii. OLAP(OnLineAnalysisProcess) purpose :

-> Database data is user to analysis the reports

-> SQL is completely QUERY based language

-> we can write queries by using SELECT, INSERT, UPDATE, DELETE, CREATE,
etc., commands

PL/SQL :- It is a programming language

It supports all SQL Queries and programming concepts


What is a Database ?

-> Where can store the data permanently for future reference

W/L - 20 ->

-> for freshers it is very important

-> for java / any front developers

->

60% -> front end appl.

40% -> backend-db

-> SQL developers -> fresher / 1+ / 2+

-> PL/SQL developers

-> fresher DBA ->

-> ETL devlopers( cognos, informatica,bi, etc.,)

Why oracle is a relational db ?

-> we try to automate one e-commerce appl.

customer_tab : cid, cname, address, pincode, mail-id, mobileno


c1 king hyd 5000016 xxxx 900090045
c2 SCOTT Sec 5000032 xxxx 900090046

order_tab : ord_id, ord_date, item_name, qty, total_amt cid


ord1 28th July mobile 1 12000 c1
ord2 28th July TV 1 34000 c10 x

std_mas: sid, sname, class


s1
s2
s3

std_maarks: sid, maths, phys, chem


s1
s3
s5 x

-> In relational datbases the relations are mainting by usign PRIMARY KEY
& FOREIGN KEY Constraints
History of Databases :
----------------------

-> What is a Data ?

-> It is a collection of raw facts

-> Data contains two parts

i. Structured data : If any data we can easily modify

ex: std_id, std_name, accno, cust_name, mobileno, etc.,

ii. Un-structured Data : if any data we can not modify

ex: std_photo, audio files, video files, google maps,


etc.,

-> What is information ?>

-> After Processing data we can achieve meaningful information

book_Mas: BOOK_ID, BOOK_NAME, AUTHOR_NAME

stock: sno, sdate, book_id, no_of_books

-> What is data store ?

-> Where we can store the data permanently

ex: books, flat files( ex: notepad, word-doc, excel sheets,


etc.,), normal databases, Relational Databases, etc.,

-> What is a Flat File ?

-> File is a collection of information stored in bytes/char. format

-> It was introduced in 1960's

-> It was a first back-end database

-> All File operations are managed by FILESYSTEM

Dis. Adv. :
-----------

-> Files will not support Datatypes

-> Files doesn't support Password mechanism

-> In Files data stored with un-structured format

-> Data Retrieval and Manipulations are very slow

-> multiple users and multiple platforms are not supported


system1--------------system2---------------system3
emp.txt(r/w)........ emp.txt(r)-----------emp.txt(r)

II. DATABASE :
--------------

-> Database is a collection of Related and Meaningful information


stored at centrally one memory location, that location name
is called as DATABASE

-> It was introduced in 1970'S

-> Database is represented with CYLINDER symbol

-> All DB operations are managed by DBMS

DBMS : It is a pre-defined s/w tools

It manages all DB operations like SELECTING, INSERTING, UPDATING,


DELETING, etc.,

dis. adv. :
-----------

-> All normal dbs are DESKTOP databases

-> Normal databases are not supported multiple users and multiple
platforms

-> It supports only some relations

-> We can not retrieving data from morethan one table

III. RELATIONAL DATABASES:


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

-> In this Databases Data will be stored in ROWS and COLUMNS format

-> All Relational Databases provides high security, bcz., it supports


password mechanism

-> Data Retrieval and Manipulations are very fast( 10 -9 nano sec.,) we
can fetch the data, bcz.,
relational dbs are supports INDEX mechanism

-> All Relational Databsaes are supports Multiple Users and Multiple
Platforms

-> Relational databases supports different types of Relations like,


PRIMARY KEY, FOREGIN KEY, etc.,

-> In Relational databases we can retrieving data from morethan one


table by using JOINS

-> All above operations are managed bY RDBMS

Ex:Different types of relational databases are...


ex: ORACLE, SQL SERVER, MY-SQL, DB2, TERADATA,
SYBASE, etc.,

ORDBMS -> Object RDBMS

OORDBMS -> Object Oriented RDBMS

ORACLE -> It is a platfrom Independent DB

ORACLE VERSIONS:
----------------

-> From oracle 1.0 to 5.0 all are trail versions

-> from 6.0 onwards commercial versions are started.

i. OLTP

ii. OLAP

** developing applications are two types

i. WINDOWS ( desktop ) applications

ii. WEB applications

PIVOT -> IT CONVERTS ROWS INTO COLUMNS

1981 10
1982 15

1981 1982
10 15

-> To develop any applications, there are 3 layers are required.

i. Presentation Layer : According to client/end-user requirement to


design GUI application

ex: HTML/JS, CSS3, Angular JS, UI desings

ii. Business Layer : To accept PL request and send to SL and to validate


client requirements
ex: JAVA, .NET, PYTHON, PHP, etc.,

iii. Storage Layer : To accept BL request and process, output sent to PL

-> To store the information permanently

-> It is also called as BACK-END/DATABASE

ex: ORACLE, SQL SERVER, MY-SQL, etc.,

Differences Between ORACLE vs SQL SERVER :


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

ORACLE SQL SERVER

i. It is a CUI based Database i. It is a GUI


based DB
In Oracle GUI editor is also available
that is : TOAD, SQL DEVELOPER, etc.,

ii. It is a Platform Indepentdent DB II. It is a


platform Dependent DB

iii. Oracle supports as a back-end III. It is mainly


prefereble Microsoft Products
different types of front-end applications

ex: Java, .Net, Python, D2K, PHP, etc., ex: VB,


VB.NET, C#.NET, ASP.NET, etc.,

iv. Oracle provides High Security IV. It provides Poor


security

oracle :
---------

select sqrt(25) from dual;

o/p: 5

sql server:
-----------

select sqrt(25)

o/p: 5

How to Install Oracle In our Systems :


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

-> Basically Oracle provided two types of S/Ws

i. Express Edition
ii. Enterprize Edition

i. Express Edition :
--------------------

-> It is a light wegihted s/w

-> To install this s/w min. 2GB RAM, 20GB HD is required

-> It is a Free licensed S/w

software link : https://www.oracle.com/database/technologies/xe-


downloads.html

ii. Enterprize Edition :


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

-> It is a licensed s/w

-> To install this s/w min. 4gb/8GB RAM, 20gh HD

-> s/w size is 2gb

software link : https://www.oracle.com/database/technologies/oracle-


database-software-downloads.html#19c
---------------

**Once Oracle installed in our systems, by defualt ORACLE provided pre-


defined DBA users

i. system ii. sys iii. ./as sysdba , etc.,

How to Create a New User ?

-> To create a new user only DBA has permission

connect to DBA user :


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

username : system
password : server

Syntax for To create a New User :


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

Create User <user_name> Identified by <password>;

ex:

Create User ora8pm Identified by lion;

** once user created, you should be grant the permissions to connect user
:
*************************************************************************
***
ex:-

Grant connect, resource to ora8pm

How to Change User Password :


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

-> either DBA or User can change password

syn:-

Alter User <user_name> Identified by <new_password>;

ex:-

Alter User ora8pm Identified by tiger;

** to see the created list of the user ?

-> In DBA user ( system/sys ) you can check.

select username from dba_users;

SQL> Select username from dba_users;

USERNAME
------------------------------
ORA8PM
SYS
SYSTEM
ANONYMOUS
APEX_PUBLIC_USER
FLOWS_FILES
APEX_040000
OUTLN
DIP
ORACLE_OCM
XS$NULL

USERNAME
------------------------------
MDSYS
CTXSYS
DBSNMP
XDB
APPQOSSYS
HR

17 rows selected.

** How to drop created users ?

-> In DBA user we can drop

syn :-
Drop User <user_name>;

ex:-

Drop User scott;

note: ** From Oracle 12c onwards before username should be place 'C##' is
required

ex: c##ora8pm, c##scott, etc.,

How to connect to Create user ?


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

username: ora8pm
password: tiger

sql>

cl scr:
-------

-> to clear the screen

ORACLE DATATYPES :
------------------

-> Datatype is a type of information stored in Memory.

-> Oracle supports two types of Datatypes

i. Simple Datatypes

-> SQL supports simple datatypes

ii. Complex Datatypes or ( user defined datatypes )

-> PL/SQL supports complex datatypes

i. Simple Datatypes :
---------------------

a. NUMBER(P,S) : P -> Precision(integer part ) S -> Scale (


fractional part )
----------------

-> This datatype accepts only Numaric Values ( Numbers )

-> Maximum Size is 38 digits ( that includes Scale part )

ex :-

EMPID NUMBER(2); -- 2 represents only no.of digits


** above column accepts value from 0 to 99

EMPID NUMBER(4);

** above column accepts value from 0 to 9999

SALARY NUMBER(5,2); 5 -> precision 2 -> scale part


(3,2);

** above column accepts value from 0 to 999.99

note: in NUMBER datatype each and every time Scale part(2) is sub-
traction from Precision part(5) i.e., ( 5 - 2 = 3)

** to accept salary upto < 100000

SALARY NUMBER(7,2);
(5,2);

ex: it accepts salary upto 99999.99

ii. CHAR(size) :
----------------

-> It is a Fixed Length Datatype

-> This datatype accepts Alpha-bets and Alpha-numaric values

-> Maximum limit is 2000 bytes/chars.

ex:-

Employ_Name Char(20);

'RAMA------'
'KRISHNA---'

Note: in CHAR datatype there is memory wastage bcz., in above first


example our INput is 4 bytes('RAMA' ) remaining 6 bytes wastage

** Mainly CHAR datatype is used for FIXED length Data

ex:- State_code char(2); 'AP','MP','UP','TS', etc.,

country_code char(3); 'IND','AUS', 'PAK', etc.,

PanCardNo char(10);

iii. VARCHAR2(SIZE) :
---------------------

-> This datatype supports Dynamic Memory Allocation

-> This datatype also accepts Alpha-bets and Alpha-Numaric Values

-> Maximum size is 4000 bytes/chars


ex:

Employ_name varchar2(10);

'rama' -> only 4 bytes are allocated

note: here there is no memory wastage

iv. DATE(size) :
----------------

-> It is a fixed length datatype

-> This datatype accepts only DATE Values

-> It occupies 7 bytes memory ( fixed )

-> Oracle Default Date format is 'DD-MON-YY'

'DD' -> day of the month

'MON' -> first three chars. of the month

'YY' -> last two digits of the year

ex:-

DOJ DATE; '04-AUG-23'

DOB DATE; '23-NOV-83' -- wrong input

-> in above 2nd exmaple oracle taken as 2083 bcz., by defualt ORACLE
taking CURRENT CENTURY

-- 23RD NOV, 1983

DOB DATE; '23-NOV-1983' -- valid input

04/08/23 -> conversion function -> '04-AUG-23'

08/23/23

LONG :
------

-> This datatype accepts alpha-bets, numarics and alpha-numaric values

-> By using long datatype we can upload DOCs also

-> maximum size is 2gb

ex:-

Remarks LONG;
emp_resume LONG;

note: table should be contain only one LONG datatype

RAW / LONG RAW :


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

-> These datatypes are supports Images, Audio Files, & Video files

-> Maximum size is 2000 bytes(RAW), 2gb(LONG RAW ) datatypes

ex:-

Emp_Photo LONG RAW;

LOB(LargeOBjects) / BLOB(Binary LOB) / CLOB(Char LOB ) :


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

-> These datatypes are accepts images, audio files and video files

-> maximum size is 4gb.

-> by using these datatypes we can upload documents(flat files) also


ex:-

Emp_Photo CLOB;

Emp_Video BLOB;

Emp_doc CLOB;

BFILE :
-------

-> this datatype can hold path of the file

-> in Oracle database single column accept maximum 4gb data.

ex:-

Emp_meeting_video bfile; 'c:\meetings\emp_meeting_video1'

SQL(Structured Query Language) :


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

-> It is a non-procedural Language

-> SQL is developed by Mr. E F CODD, in 1980s at IBM

-> SQL supports IN-LINE commands

-> SQL is a common Language for any relational databases

ex: oracle sql server my-sql teradata sql-


lite
sql sql sql sql
sql
** SQL is a main language and it is devided into 5 sub-languages

I. DDL( Data Definition Language )

i.Create ii. Alter iii. Rename iv. Truncate v. Drop

II. DML( Data Manipulation Language )

i. Insert ii. Update iii. Delete iv. Insert all v.


Merge

III. DRL/DQL( Data Retrival/Query Language )

i. SELECT

IV. DCL( Data Control Language )

i. Grant ii. Revoke

V. TCL( Transaction Control Language )

i. Commit ii. Savepoint iii. Rollback

I. DDL( Data Definition Language )

i.Create ii. Alter iii. Rename iv. Truncate v. Drop

i. Create :
-----------

-> This command is used to create a table / any db objects

-> examples of different DB Objects are...

ex: TABLE, VIEWS, INDEXES, SEQUENCES, SYNONYMS, ROLES, etc.,

TABLE :
-------

-> Table is a collection of information stored in Rows and Columns


format

-> It is common db object for any relational databases

-> Each table maximum it accepts 1024 columns(attributes) and un-


limited records(tuples)

Syntax :
--------

Create Table <table_name> ( col1 datatype(size),


col2 datatype(size),
col3 datatype(size)),
.
.
);
Ex:-

-- Create a employee db table with Employee id, Employee name, salary


& deptno

Create Table Employee ( EmpId Number(2),


Ename Varchar2(10),
Salary Number(6,2),
Deptno Number(2)
);

';' -> terminator pointer

ex:-

-- create a customer table with customer id, customer name, address,


mobileno, customer photo & pincode

Create table cust_db( cid varchar2(10),


cname varchar2(20),
address varchar2(20),
mobileno number(10),
cust_photo blob,
pincode number(6)
);

-- create a ordered table with order id, order date, item name,
quantity, date of booking, date of delivery, customer id & remarks

Create table order_db( ord_id varchar2(10),


ord_date date,
item_name varchar2(10),
qty number(2),
dob date,
dod date,
cust_id varchar2(10),
remarks varchar2(50)
);

** to see the created tables then...

SQL> Select * from tab;

TNAME TABTYPE CLUSTERID


------------------------------ ------- ----------
CUST_DB TABLE
EMPLOYEE TABLE
ORDER_DB TABLE

cl scr : to clear the screen

DESC <table_name> :
-------------------

-> It shows strucuture of the table


ex:-

SQL> desc employee;


Name Null? Type
----------------------------------------- -------- ------------
EMPID NUMBER(2)
ENAME VARCHAR2(10)
SALARY NUMBER(6,2)
DEPTNO NUMBER(2)

ii. ALTER command :


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

-> This command is used to modify structure of the table

-> This command works on columns structure only

-> It has 4 options

a. add b. modify c. rename d. drop

a. add :
--------

-> used to add a new column / columns into existing table

ex:-

-- to add a JOB & REMARKS column in EMPLOYEE table

SQL> Alter Table Employee ADD( Job Varchar2(10), Remarks varchar2(50) );

Table altered.

SQL> desc employee;


Name Null? Type
----------------------------------------- -------- ---------------------
-
EMPID NUMBER(2)
ENAME VARCHAR2(10)
SALARY NUMBER(6,2)
DEPTNO NUMBER(2)
JOB VARCHAR2(10)
REMARKS VARCHAR2(50)

b. modify :
-----------

-> Used to increase/decrease size of the column or to change datatype


of a column

** to increase size of EMPID from NUMBER(2) to NUMBER(4)

SQL> Alter Table Employee MODIFY ( Empid Number(4) );

Table altered.

SQL> desc employee;


Name Null? Type
----------------------------------------- -------- --------------------
EMPID NUMBER(4)
ENAME VARCHAR2(10)
SALARY NUMBER(6,2)
DEPTNO NUMBER(2)
JOB VARCHAR2(10)
REMARKS VARCHAR2(50)

** to CHANGE datatype of a column :


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

-- to change EMPID NUMBER to VARCHAR2 datatype

SQL> Alter Table Employee MODIFY ( Empid Varchar2(4) );

Table altered.

SQL> desc employee;


Name Null? Type
----------------------------------------- -------- ------------------
EMPID VARCHAR2(4)
ENAME VARCHAR2(10)
SALARY NUMBER(6,2)
DEPTNO NUMBER(2)
JOB VARCHAR2(10)
REMARKS VARCHAR2(50)

Note : to change datatype of a column, that column should be EMPTY

iii. rename( column ) :


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

-> Used to rename a column name permanently

ex:-

-- To rename a SALARY to BASIC_SALARY

SQL> Alter table Employee RENAME COLUMN Salary to Basic_Salary;

Table altered.

SQL> desc employee;


Name Null? Type
----------------------------------------- -------- ---------------------
EMPID VARCHAR2(4)
ENAME VARCHAR2(10)
BASIC_SALARY NUMBER(6,2)
DEPTNO NUMBER(2)
JOB VARCHAR2(10)
REMARKS VARCHAR2(50)

iv. drop ( column ) :


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

-> Used to drop un-used columns from the database permanently

ex:-
-- to drop a single column

Alter Table Employee DROP COLUMN JOB;

-- to drop multiple columns

Alter Table Employee DROP ( JOB, REMARKS );

III. RENAME( table ) :


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

-> Used to RENAME a table name

syn:-

RENAME <old_table_name> TO <new_table_name>;

ex:-

RENAME Employee to Employee_db;

SQL> desc employee;


ERROR:
ORA-04043: object employee does not exist

SQL> desc employee_db;


Name Null? Type
----------------------------------------- -------- ------------------
EMPID VARCHAR2(4)
ENAME VARCHAR2(10)
BASIC_SALARY NUMBER(6,2)
DEPTNO NUMBER(2)
JOB VARCHAR2(10)
REMARKS VARCHAR2(50)

IV. TRUNCATE :
--------------

-> This command used to DELETE ALL RECORDS from the table Permanently

-> Table is Structure is Present

-> Rollback(Undo) not supported

ex:-

Truncate Table Employee_db;

V. DROP( TABLE ) :
-------------------

-> This command is used to delete all records and structure from the
DB Permanently

-> Table is not present

-> Rollback not supported, but we can restore the table by using
FLASHBACK queries
syn:-

Drop Table <table_name>;

ex:-

Drop Table Employee;

II. DML( Data Manipulation Language ) :


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

-> This language commands are used to manipulate exsiting table's


data

-> It has 5 commands

i. insert ii. update iii. delete iv.


insert all v. merge

i. insert :
-----------

-> Used to insert new record/records into existing table

a. Inserting data into all columns :


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

syn:-

Insert Into <table_name> values( data1, data2, .... );

ex:-

SQL> Insert into employee_db values( '101', 'King', 5000, 10,


'Manager', 'No' );

1 row created.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO JOB REMARKS


---- ---------- ------------ ---------- ---------- ---------
101 King 5000 10 Manager No

SQL> Insert into employee_db values( '102', 'Scott', 6000, 20, 'Clerk'
);
Insert into employee_db values( '102', 'Scott', 6000, 20, 'Clerk' )
*
ERROR at line 1:
ORA-00947: not enough values

b. Inserting Data into required columns :


-----------------------------------------
syn:-

Insert into <table_name>( col1, col2,... ) values ( data1, data2,.... );

ex:-

Insert Into Employee_db( EMPID, ENAME, BASIC_SALARY, DEPTNO ) values (


102, 'Scott', 4000, 20 );

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO JOB REMARKS


---- ---------- ------------ ---------- ---------- ---------
101 King 5000 10 Manager No
102 Scott 4000 20

Inseting NULLs:
---------------

-> While inserting data, if we don't have any column values instead of
that column values to use NULLs

-> There are two types of NULLs supported by ORACLE

i. EXPLICIT NULL :
==================

-> NULLs are inserted by user Explicitely is called as Explicit NULL

EX:-

-- If we don't have BASIC_SALARY, JOB & REMARKS

SQL> Insert Into employee_db values( '103', 'Smith', NULL, 30, NULL, NULL
);

1 row created.

SQL> select * from employee_db;

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO JOB REMARKS


---- ---------- ------------ ---------- ---------- ---------
101 King 5000 10 Manager No
102 Scott 4000 20
103 Smith 30

ii. IMPLICIT NULL :


===================

-> NULLs are inserted by ORACLE automatically is called as Implicit


NULL

ex:-
-- If we don't have BASIC_SALARY, JOB & REMARKS

sql> Insert Into Employee_db( EMPID, ENAME, DEPTNO ) Values ( 104,


'James', 20 );

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO JOB REMARKS


---- ---------- ------------ ---------- ---------- ---------
101 King 5000 10 Manager No
102 Scott 4000 20
103 Smith 30
104 James 20

** to insert Multiple records continuously then Oracle provided

I. Single &

II. Double &&

I. Single & :
-------------

-> Used to inserting data at run-time

ex:-

SQL> Insert Into Employee_db values( &Empid, &Ename, &basic_salary,


&deptno, &job, &remarks );
Enter value for empid: 105
Enter value for ename: 'Allen'
Enter value for basic_salary: 3500
Enter value for deptno: 10
Enter value for job: 'Clerk'
Enter value for remarks: 'No'
old 1: Insert Into Employee_db values( &Empid, &Ename, &basic_salary,
&deptno, &job, &remarks )
new 1: Insert Into Employee_db values( 105, 'Allen', 3500, 10,
'Clerk', 'No' )

1 row created.

SQL> /
Enter value for empid: 106
Enter value for ename: 'Blake'
Enter value for basic_salary: 6500
Enter value for deptno: 30
Enter value for job: 'Analyst'
Enter value for remarks: 'No'
old 1: Insert Into Employee_db values( &Empid, &Ename, &basic_salary,
&deptno, &job, &remarks )
new 1: Insert Into Employee_db values( 106, 'Blake', 6500, 30,
'Analyst', 'No' )

1 row created.

SQL> select * from employee_db;


EMPI ENAME BASIC_SALARY DEPTNO JOB REMARKS
---- ---------- ------------ ---------- ---------- ---------
101 King 5000 10 Manager No
102 Scott 4000 20
103 Smith 30
104 James 20
105 Allen 3500 10 Clerk No
106 Blake 6500 30 Analyst No

'/' -> To execute SQL Buffer's query

SQL BUFFER :
------------

-> SQL buffer is a Temporary Buffer and it holds latest executed query

II. Double && :


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

-> Used to Insert Duplicate data into table

-> Inside the table if any column values is fixed / common then to use
this &&

ex:-

-- In employee table all employee salaries are rs.5000 fixed

SQL> DESC EMPLOYEE_DB;


Name Null? Type
----------------------------------------- -------- -------------
EMPID VARCHAR2(4)
ENAME VARCHAR2(10)
BASIC_SALARY NUMBER(6,2)
DEPTNO NUMBER(2)

SQL> insert into employee_db values( '101', 'king', 5000, 10 );

1 row created.

SQL> insert into employee_db values( &empid, &ename, &&basic_salary,


&deptno);
Enter value for empid: '102'
Enter value for ename: 'scott'
Enter value for basic_salary: 9000
Enter value for deptno: 20

1 row created.

SQL> /
Enter value for empid: '103'
Enter value for ename: 'james'
Enter value for deptno: 30

1 row created.
SQL> /
Enter value for empid: '104'
Enter value for ename: 'allen'
Enter value for deptno: 20

1 row created.

SQL> /
Enter value for empid: '105'
Enter value for ename: 'blake'
Enter value for deptno: 30

1 row created.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO


---- ---------- ------------ ----------
101 king 5000 10
102 scott 9000 20
103 james 9000 30
104 allen 9000 20
105 blake 9000 30

ii. Delete Command :


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

-> This command is used to delete all records or specified records from
table temporarily

-> Rollback is supported

-> Table is present

syn:-

Delete from <table_name> [ WHERE <condition> ];

ex:-

Delete from employee_db where Empid='105';

Delete from employee_db; -- all records deleted

iii. Update Command :


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

-> Used to modify / chanage existing table's data

-> By using UPDATE command we can update either single or group of


columns

syn:-

Update <table_name> set <col1>=<val1> [, <col2>=<val2>,.... where


<condition>];
ex:-

-- write a query to increment all employee salaries with 20%

SQL> Update Employee_db Set Basic_Salary = Basic_Salary + Basic_Salary *


0.2;
Update Employee_db Set Basic_Salary = Basic_Salary + Basic_Salary * 0.2
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column

SQL> alter table employee_db modify basic_salary number(7,2);

Table altered.

SQL> desc employee_db;


Name Null? Type
----------------------------------------- -------- ---------------------
-------
EMPID VARCHAR2(4)
ENAME VARCHAR2(10)
BASIC_SALARY NUMBER(7,2)
DEPTNO NUMBER(2)

SQL> Update Employee_db Set Basic_Salary = Basic_Salary + Basic_Salary *


0.2;

5 rows updated.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO


---- ---------- ------------ ----------
101 king 6000 10
102 scott 10800 20
103 james 10800 30
104 allen 10800 20
105 blake 10800 30

ex2:-

-- waq to set employee name as ANAND, Salary as 8500 for empid 1003

SQL> Update Employee_db set ename ='Anand', Basic_Salary=8500 Where


Empid=103;

1 row updated.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO


---- ---------- ------------ ----------
101 king 6000 10
102 scott 10800 20
103 Anand 8500 30
104 allen 10800 20
105 blake 10800 30

ex2:-
-- waq to delete all Employee Salaries

SQL> Update Employee_db set Basic_salary=NULL;

5 rows updated.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO


---- ---------- ------------ ----------
101 king 10
102 scott 20
103 Anand 30
104 allen 20
105 blake 30

NOTE: to delete COLUMN values then use UPDATE command by using NULL

SQL> Update employee_db set basic_salary=&basic_salary where


empid=&Empid;
Enter value for empid: 102
old 1: Update employee_db set basic_salary=&basic_salary where
empid=&Empid
new 1: Update employee_db set basic_salary=9000 where empid=102

1 row updated.

SQL> Update employee_db set basic_salary=&basic_salary where


empid=&Empid;
Enter value for empid: 103
old 1: Update employee_db set basic_salary=&basic_salary where
empid=&Empid
new 1: Update employee_db set basic_salary=9000 where empid=103

1 row updated.

SQL> /
Enter value for empid: 104
old 1: Update employee_db set basic_salary=&basic_salary where
empid=&Empid
new 1: Update employee_db set basic_salary=9000 where empid=104

1 row updated.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO


---- ---------- ------------ ----------
101 king 6500 10
102 scott 9000 20
103 Anand 9000 30
104 allen 9000 20
105 blake 30

ex3:-

-- add a mail_id column into employee_db table


-- update all employee mail ids with their Employee name

step 1:
-------

SQL> Alter Table Employee_db Add( mail_id Varchar(20) );

Table altered.

SQL> desc employee_db;


Name Null? Type
----------------------------------------- -------- ----------------
EMPID VARCHAR2(4)
ENAME VARCHAR2(10)
BASIC_SALARY NUMBER(7,2)
DEPTNO NUMBER(2)
MAIL_ID VARCHAR2(20)

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO MAIL_ID


---- ---------- ------------ ---------- --------------------
101 king 6500 10
102 scott 9000 20
103 Anand 9000 30
104 allen 9000 20
105 blake 30

SQL> Update Employee_db set Mail_id = Ename || '@gmail.com';

5 rows updated.

SQL> select * from employee_db;

EMPI ENAME BASIC_SALARY DEPTNO MAIL_ID


---- ---------- ------------ ---------- --------------------
101 king 6500 10 [email protected]
102 scott 9000 20 [email protected]
103 Anand 9000 30 [email protected]
104 allen 9000 20 [email protected]
105 blake 30 [email protected]

|| -> it is a concatination operator and used to add multiple strings

III. DRL(Data Retrieval Language ) :


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

-> It has only one command

i. SELECT

i. SELECT :
-----------

-> Used to retrieving/fetching data from tables / db objects

syn:-
Select * / column_list from <table_name> [WHERE <condition>/
GROUP BY Clause/
HAVING Clause /
ORDER BY clause ];
ex:-

Select * from Employee_db;

SQL> Select Empid, Mail_id from Employee_db;

EMPI MAIL_ID
---- --------------------
101 [email protected]
102 [email protected]
103 [email protected]
104 [email protected]
105 [email protected]

** Oracle provided some demo tables for practice purpose those tables
are...

i. EMP ii. DEPT iii. SALGRADE iv. BONUS v. DUAL

Oracle Demo Tables For Practise:


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

DROP TABLE EMP;


DROP TABLE DEPT;
DROP TABLE BONUS;
DROP TABLE SALGRADE;
DROP TABLE DUMMY;

CREATE TABLE EMP


(EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2));

INSERT INTO EMP VALUES


(7369, 'SMITH', 'CLERK', 7902,
TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,
TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698,
TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839,
TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698,
TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839,
TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839,
TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566,
TO_DATE('09-DEC-1982', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL,
TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698,
TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, 0, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788,
TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 950, NULL, 30);
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782,
TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, 10);

CREATE TABLE DEPT


(DEPTNO NUMBER(2),
DNAME VARCHAR2(14),
LOC VARCHAR2(13) );

INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');


INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');

CREATE TABLE BONUS


(ENAME VARCHAR2(10),
JOB VARCHAR2(9),
SAL NUMBER,
COMM NUMBER);

CREATE TABLE SALGRADE


(GRADE NUMBER,
LOSAL NUMBER,
HISAL NUMBER);

INSERT INTO SALGRADE VALUES (1, 700, 1200);


INSERT INTO SALGRADE VALUES (2, 1201, 1400);
INSERT INTO SALGRADE VALUES (3, 1401, 2000);
INSERT INTO SALGRADE VALUES (4, 2001, 3000);
INSERT INTO SALGRADE VALUES (5, 3001, 9999);

CREATE TABLE DUMMY


(DUMMY NUMBER);

INSERT INTO DUMMY VALUES (0);


COMMIT;

CRUID operations

ORACLE Operators :
------------------

-> Oracle supported Operators are..

i. Arithmetic Operators : +, -, * , /

ii. Relational Operators : >, <, >=, <=, =, != or <>

iii. Logical Operators : AND, OR, NOT

iv. Assignment Operators : := ( used to assign to Values into a


variable ex: a := 10 )

v. Set Operators : UNION ALL, UNION, INTERSECT, MINUS

vi. Special Operators : IN,NOT IN, BETWEEN, NOT BETWEEN, LIKE, NOT LIKE,
IS NULL, IS NOT NULL

-- waq to display who 30th dept. SALESMANs

SQL> SELECT * FROM EMP WHERE DEPTNO=30 AND JOB='SALESMAN';

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30

-- waq to display 10, 20th depts. CLERKS

select * from emp where deptno=10 or deptno=20 and job='CLERK';

EMPNO ENAME JOB MGR HIREDATE SAL COMM


DEPTNO
------ ---------- --------- ---------- --------- ---------- ---------- --
--------
7369 SMITH CLERK 7902 17-DEC-80 800
20
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7934 MILLER CLERK 7782 23-JAN-82 1300
10

Priority of Operators :
-----------------------

i. Arithmetic Operators : BODMAS rules { }, ( ), /, *, +, -

ii. Relational Operators: All are same priority

iii. Logical Operators: NOT, AND, OR

iv. Set operators: NO Priority, all are same

v. special operators: NOT IN, IN, NOT BETWEEN, BETWEEN, .....

SQL> select * from emp where ( deptno=10 or deptno=20 ) and job='CLERK';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

-- waq to display whose employee nos. are matched with 7788, 7369, 7839
& 7902

SQL> SELECT * FROM EMP WHERE EMPNO=7788 OR EMPNO=7369 OR EMPNO=7839 OR


EMPNO=7902;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7902 FORD ANALYST 7566 03-DEC-81 3000 20

Special Operators :
-------------------

-> Special operators are used to improves the performance while


retrieving or manipulating data

-> by using special operator we can reduce no.of conditions in WHERE


clause

IN :
-----

-> this operator used to compare multiple values

-> it supports all datatypes.

-- waq to display whose employee nos. are matched with 7788, 7369, 7839
& 7902
SQL> select * from emp where empno IN ( 7788, 7839, 7369, 7902 );

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7902 FORD ANALYST 7566 03-DEC-81 3000 20

ex:-

-- waq to display 10, 30th depts. CLERKS & SALESMANs

SQL> select * from emp where deptno in ( 10, 30 ) and job in


('CLERK','SALESMAN');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7900 JAMES CLERK 7698 03-DEC-81 950 30
7934 MILLER CLERK 7782 23-JAN-82 1300 10

6 rows selected.

NOT IN :
--------

-> this operator used to compares other than given list of values

-> It supports all datatypes

ex:-

-- waq to display whose names not matched with SMITH, ALLEN & FORD

SQL> SELECT * FROM EMP WHERE ENAME NOT IN ( 'SMITH', 'ALLEN', 'FORD');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7934 MILLER CLERK 7782 23-JAN-82 1300 10

11 rows selected.

BETWEEN :
---------
-> this operator compares the data based on given RANGE

-> it supports all datatypes

ex:-

-- waq to display who are getting salaries 1000 to 4000

SQL> select * from emp where sal between 1000 and 4000;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

11 rows selected.

note: BETWEEN operator it includes lower and upper bound values

NOT BETWEEN :
-------------

-> this operator used to compares other than given range

-> it supports all datatypes

ex:-

-- waq to display who are not joined in 81 year

SQL> select * from emp where hiredate not between '01-jan-81' and '31-
dec-81';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

note: it excludes LOWER and UPPER bound values

LIKE :
-------

-> this operator used to compares data based on given pattern

-> it supports two wild characters


i. % ( any character )

ii. _ ( one or more characters )

-> LIKE operator supports only CHAR values

ex:-

-- waq to display whose names are start with 'S' char

SQL> select * from emp where ename LIKE 'S%';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20

-- whose names are end with 'S' char

SQL> select * from emp where ename LIKE '%S';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7566 JONES MANAGER 7839 02-APR-81 2975 20
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30

-- Whose names having 'LL'

SQL> select * from emp where ename LIKE '%LL%';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7934 MILLER CLERK 7782 23-JAN-82 1300 10

-- Whose names 2nd char. start with 'D'

SQL> select * from emp where ename like '_D%';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7876 ADAMS CLERK 7788 12-JAN-83 1100 20

-- whose names staring and ending with 's'

SQL> SELECT * FROM EMP WHERE ENAME LIKE 'S%S';

-- whose names contains 5 chars.

SQL> SELECT * FROM EMP WHERE ENAME LIKE '_____';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30

8 rows selected.

NOT LIKE:
---------

-- waq to display whose names not contains 'S'

SQL> select ENAME from emp where ENAME NOT LIKE '%S%';

ENAME
----------
ALLEN
WARD
MARTIN
BLAKE
CLARK
KING
TURNER
FORD
MILLER

9 rows selected.

-- who are joined in 81 year

SQL> select * from emp where hiredate like '%81';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20

10 rows selected.

-- who are joined in FEBRUARY month

SQL> select * FROM EMP WHERE HIREDATE LIKE '%FEB%';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30

SQL> select * FROM EMP WHERE HIREDATE LIKE '%-FEB-%';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30

-- waq to display who joined in first 9 days

IS NULL :
--------

-> Used to compare NULL values

-> It supports all datatypes

ex:-

-- waq to display who are not getting commmission

SQL> select * from emp where comm IS NULL;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7566 JONES MANAGER 7839 02-APR-81 2975 20
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

10 rows selected.

IS NOT NULL :
-------------

-- waq to display who are getting commission

SQL> select * from emp where comm IS NOT NULL;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30

Examples :
----------

-- write a query to display all employee details

SQL> set line 100;


SQL> set pagesize 100;
SQL> select *from emp;
EMPNO ENAME JOB MGR HIREDATE SAL
COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 800
20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7566 JONES MANAGER 7839 02-APR-81 2975
20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7788 SCOTT ANALYST 7566 09-DEC-82 3000
20
7839 KING PRESIDENT 17-NOV-81 5000
10
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7900 JAMES CLERK 7698 03-DEC-81 950
30
7902 FORD ANALYST 7566 03-DEC-81 3000
20
7934 MILLER CLERK 7782 23-JAN-82 1300
10

14 rows selected.

-- waq to display dept. details

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

-- waq to display SASLGRADE details

SQL> select *from salgrade;

GRADE LOSAL HISAL


---------- ---------- ----------
1 700 1200
2 1201 1400
3 1401 2000
4 2001 3000
5 3001 9999

-- waq to display who are working in 10th dept.


SQL> select * from emp where DEPTNO=10;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10

WHERE :- used to filter the data

syn:- WHERE <col_name> = <constant>/<expression>;

-- waq to display who are working as MANAGERs

SQL> select * from emp where job='MANAGER';

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7566 JONES MANAGER 7839 02-APR-81 2975
20
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7782 CLARK MANAGER 7839 09-JUN-81 2450
10

-- waq to display who are joined after 81 year

SQL> select * from emp WHERE hiredate> '31-dec-81';

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7788 SCOTT ANALYST 7566 09-DEC-82 3000
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7934 MILLER CLERK 7782 23-JAN-82 1300
10

-- waq to display who are getting salaries morethan rs.3000/-

SQL> select * from emp where sal >3000;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7839 KING PRESIDENT 17-NOV-81 5000
10

-- waq to display to find 7369 employee name


SQL> select ename from emp where empno=7369;

ENAME
----------
SMITH

-- waq to display who are working in 10, 20 depts.

TRUTH TABLES :
--------------

AND
----
I1 I2 O/P

T T T
T F F
F T F
F F F

OR
----

I1 I2 O/P

T T T
T F T
F T T
F F F

NOT
---

I1 O/P

T F
F T

SQL> select * from emp where deptno=10 and deptno=20;

no rows selected

SQL> select * from emp where deptno=10 OR deptno=20;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 800
20
7566 JONES MANAGER 7839 02-APR-81 2975
20
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7788 SCOTT ANALYST 7566 09-DEC-82 3000
20
7839 KING PRESIDENT 17-NOV-81 5000
10
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7902 FORD ANALYST 7566 03-DEC-81 3000
20
7934 MILLER CLERK 7782 23-JAN-82 1300
10

8 rows selected.

ORACLE BUILT-IN FUNCTIONS :


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

-> Oracle pre-defined functions are called as Built-in functions

-> Basically functions are two types

i. Pre-defined Function :-

-> These functions are defined by Oracle. SQL supports pre-


defined functions

ii. User-defined Function :-

-> According to client requirement we can write own


functions are called as user-defined functions

-> PL/SQL supports user-defined functions

-> what is a function ?

-> Function is a self-contained block and it returns a value

I. Pre-defined Function :
*************************

-> Pre-defined functions are classified into Four types

i. Column Level Functions

ii. Group Functions

iii. Conversion Functions

iv. General Functions

** In ORACLE all functions are executed by using 'SELECT' statement

i. Column Level Functions :


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

-> These functions are executed on each and every column value

-> Column Level Functions are classified into three types

a. Number Functions
b. Character Functions

c. Date Functions

a. Number Functions :
---------------------

-> These functions are supports only Numaric Values only

ABS() :
-------

-> This function converts -ve value to +ve

ex:-

SQL> SELECT ABS(-100) FROM EMP;

ABS(-100)
---------
100
100
100
100
100
100
100
100
100
100
100
100
100
100

14 rows selected.

SQL> SELECT ABS(-100) FROM DEPT;

ABS(-100)
---------
100
100
100
100

SQL> SELECT ABS(-100) FROM DUAL;

ABS(-100)
---------
100

NOTE: above executions, DUAL table contains only one record so, ABS
function called only 1 time.

ii. POWER() :
-------------

-> It returns Power value


SQL> select power(2,3) FROM DUAL;

POWER(2,3)
----------
8

iii. SQRT() :
-------------

-> This function returns SQRT value

SQL> select sqrt(25) from dual;

SQRT(25)
--------
5

SQL> select sqrt(625) from dual;

SQRT(625)
---------
25

SQL> select sqrt(-625) from dual;


select sqrt(-625) from dual
*
ERROR at line 1:
ORA-01428: argument '-625' is out of range

note: on -ve values we can't find SQRT

SQL> select sqrt( abs( -625) ) from dual;

SQRT(ABS(-625))
---------------
25

MOD() :
--------

-> This function returns remainder

ex:-

SQL> select mod(10,2) from dual;

MOD(10,2)
---------
0

SQL>
SQL> select mod(13,2) from dual;

MOD(13,2)
---------
1

-- waq to display who are getting Even Salaries


SQL> select * from emp where mod( sal, 2 ) = 0;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

13 rows selected.

-- to display ODD records

SQL> select * from emp where mod( sal, 2 ) != 0;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7566 JONES MANAGER 7839 02-APR-81 2975 20

SIGN() :
--------

-> this function returns

-> if input value is +ve then returns 1

-ve then returns -1

0 then returns 0

ex:-

SQL> Select sign(1000) from dual;

SIGN(1000)
----------
1

SQL> Select sign(-1000) from dual;

SIGN(-1000)
-----------
-1

SQL> Select sign(0) from dual;

SIGN(0)
-------
0
SIN() :
-------

SELECT SIN(90) FROM DUAL;

COS() :
-------

SELECT COS(90) FROM DUAL;

TAN() :
-------

SELECT TAN(90) FROM DUAL;

ROUND() :
---------

-> this function is rounded to nearest value, while rounding it takes


avg. value 5

SQL> SELECT ROUND(16.8) FROM DUAL; -- 8 >=5 => TRUE

ROUND(16.8)
-----------
17

SQL> SELECT ROUND(16.3) FROM DUAL; -- 3 >=5 => FALSE

ROUND(16.3)
-----------
16

SQL> SELECT ROUND(16.79,1) FROM DUAL; -- 7>= 5

ROUND(16.79,1)
--------------
16.8

NOTE: 1 means to display output upto after decimal part 1 digit

2 means to display output upto after decimal part 2 digits

SQL> SELECT ROUND(16.5,1) FROM DUAL;

ROUND(16.5,1)
-------------
16.5

SQL> SELECT ROUND(16.748,2) FROM DUAL; 8 >=5

ROUND(16.748,2)
---------------
16.75

CEIL :
------
-> this function rounded upper bound value

SQL> SELECT CEIL(16.7) FROM DUAL;

CEIL(16.7)
----------
17

TRUNC() :
---------

-> this function is not rounded to nearest value

-> Just it truncated value

ex:-

SQL> SELECT TRUNC(16.8) FROM DUAL;

TRUNC(16.8)
-----------
16

SQL> SELECT TRUNC(16.76,1) FROM DUAL;

TRUNC(16.76,1)
--------------
16.7

SQL> SELECT TRUNC(16.768,2) FROM DUAL;

TRUNC(16.768,2)
---------------
16.76

16.65 => 17 RS.

16.45 => 16 RS.

FLOOR :
-------

-> this function returns lower bound value

SQL> SELECT FLOOR(16.7) FROM DUAL;

FLOOR(16.7)
-----------
16

-- waq to display each employee daily wages

SQL> select empno, round( sal / 30 ) from emp;

EMPNO ROUND(SAL/30)
------ -------------
7369 27
7499 53
7521 42
7566 99
7654 42
7698 95
7782 82
7788 100
7839 167
7844 50
7876 37
7900 32
7902 100
7934 43

14 rows selected.

-- to display each employee experience in years

SYSDATE :- It returns today current server date and time

SQL> select sysdate from dual;

SYSDATE
---------
14-AUG-23

SQL> select empno, sysdate - hiredate from emp;

EMPNO SYSDATE-HIREDATE
------ ----------------
7369 15581
7499 15516
7521 15514
7566 15475
7654 15296
7698 15446
7782 15407
7788 14859
7839 15246
7844 15316
7876 14825
7900 15230
7902 15230
7934 15179

14 rows selected.

SQL> select empno, (sysdate - hiredate)/365 from emp;

EMPNO (SYSDATE-HIREDATE)/365
------ ----------------------
7369 42.687
7499 42.509
7521 42.504
7566 42.397
7654 41.906
7698 42.317
7782 42.211
7788 40.709
7839 41.77
7844 41.961
7876 40.616
7900 41.726
7902 41.726
7934 41.586

14 rows selected.

SQL> select empno, round( (sysdate - hiredate)/365 ) from emp;

EMPNO ROUND((SYSDATE-HIREDATE)/365)
------ -----------------------------
7369 43
7499 43
7521 43
7566 42
7654 42
7698 42
7782 42
7788 41
7839 42
7844 42
7876 41
7900 42
7902 42
7934 42

14 rows selected.

ii. CHARACTER FUNCTIONS :


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

-> These functions are supports only char. values

lower() :
---------

-> This function converts any formated string to lower case

SQL> SELECT LOWER('NARESH IT') FROM DUAL;

LOWER('NA
---------
naresh it

upper() :
---------

-> this function converts any formated string to upper case

SQL> select upper('naresh it') from dual;

UPPER('NA
---------
NARESH IT
INITCAP() :
-----------

-> this function returns initial capital letter

SQL> select initcap('NARESH IT, HYDERABAD.') FROM DUAL;

INITCAP('NARESHIT,HYD
---------------------
Naresh It, Hyderabad.

-- waq to display 'smith' employee details

SQL> select * from emp where upper(ename)='SMITH';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20

SQL> select * from emp where lower(ename)='smith';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20

LENGTH() :
----------

-> this function returns length of the string

SQL> select length('NARESH IT') FROM DUAL;

LENGTH('NARESHIT')
------------------
9

-- waq to display which employee names contains morethan 5 chars.

SQL> select ename from emp where length(ename) >5;

ENAME
----------
MARTIN
TURNER
MILLER

SQL> select ename, lower(ename), upper(ename), initcap(ename),


length(ename) from emp;

ENAME LOWER(ENAM UPPER(ENAM INITCAP(EN LENGTH(ENAME)


---------- ---------- ---------- ---------- -------------
SMITH smith SMITH Smith 5
ALLEN allen ALLEN Allen 5
WARD ward WARD Ward 4
JONES jones JONES Jones 5
MARTIN martin MARTIN Martin 6
BLAKE blake BLAKE Blake 5
CLARK clark CLARK Clark 5
SCOTT scott SCOTT Scott 5
KING king KING King 4
TURNER turner TURNER Turner 6
ADAMS adams ADAMS Adams 5
JAMES james JAMES James 5
FORD ford FORD Ford 4
MILLER miller MILLER Miller 6

14 rows selected.

LPAD() :
--------

-> this function returns left side paddings( spaces )

SQL> SELECT LPAD('NARESH',10) FROM DUAL;

LPAD('NARE
----------
NARESH

** To fill the spaces with special characters

SQL> select lpad('NARESH',10,'*') FROM DUAL;

LPAD('NARE
----------
****NARESH

RPAD() :
--------

-> this function returns rightside paddings

SQL> select rpad('NARESH',10,'*') FROM DUAL;

RPAD('NARE
----------
NARESH****

** to display bothsides

ex: ***NARESH IT***

SQL> SELECT LPAD('NARESH IT',12,'*') FROM DUAL;

LPAD('NARESH
------------
***NARESH IT

SQL> SELECT RPAD( LPAD('NARESH IT',12,'*'),15, '*' ) FROM DUAL;

RPAD(LPAD('NARE
---------------
***NARESH IT***
CONCAT() :
----------

-> this function used to concat two strings at a time

ex:-

SQL> select concat('NARESH','IT') FROM DUAL;

CONCAT('
--------
NARESHIT

SQL> select concat('NARESH','IT','AMEERPET') FROM DUAL;


select concat('NARESH','IT','AMEERPET') FROM DUAL
*
ERROR at line 1:
ORA-00909: invalid number of arguments

Nested functions :
------------------

SQL> select concat( concat('NARESH','IT'), 'Ameerpet') FROM DUAL;

CONCAT(CONCAT('N
----------------
NARESHITAmeerpet

SQL> select concat( concat('NARESH ','IT,'), 'Ameerpet.') FROM DUAL;

CONCAT(CONCAT('NARE
-------------------
NARESH IT,Ameerpet.

** to concat multiple strings continusouly then Oracle provided ( || )


concatination operator

ex:-

SQL> select 'Mr.'||'Siva '||'Rama '||'Krishna '||'Raju' from dual;

'MR.'||'SIVA'||'RAMA'||'K
-------------------------
Mr.Siva Rama Krishna Raju

-- waq to display followig format output

i. Mr. Smith is working as a Clerk

ii. Mr. Smith is working as a Clerk and getting Annual Salary Rs.60000

SQL> Select 'Mr.'||Ename||' is working as a '|| Job from Emp;

'MR.'||ENAME||'ISWORKINGASA'||JOB
---------------------------------------
Mr.SMITH is working as a CLERK
Mr.ALLEN is working as a SALESMAN
Mr.WARD is working as a SALESMAN
Mr.JONES is working as a MANAGER
Mr.MARTIN is working as a SALESMAN
Mr.BLAKE is working as a MANAGER
Mr.CLARK is working as a MANAGER
Mr.SCOTT is working as a ANALYST
Mr.KING is working as a PRESIDENT
Mr.TURNER is working as a SALESMAN
Mr.ADAMS is working as a CLERK
Mr.JAMES is working as a CLERK
Mr.FORD is working as a ANALYST
Mr.MILLER is working as a CLERK

14 rows selected.

SQL> Select 'Mr.'||Ename||' is working as a '|| Job || ' and getting


Annual Salary Rs.'||(sal*12) from emp;

'MR.'||ENAME||'ISWORKINGASA'||JOB||'ANDGETTINGANNUALSALARYRS.'||(SAL*12)
-------------------------------------------------------------------------
---------------------------
Mr.SMITH is working as a CLERK and getting Annual Salary Rs.9600
Mr.ALLEN is working as a SALESMAN and getting Annual Salary Rs.19200
Mr.WARD is working as a SALESMAN and getting Annual Salary Rs.15000
Mr.JONES is working as a MANAGER and getting Annual Salary Rs.35700
Mr.MARTIN is working as a SALESMAN and getting Annual Salary Rs.15000
Mr.BLAKE is working as a MANAGER and getting Annual Salary Rs.34200
Mr.CLARK is working as a MANAGER and getting Annual Salary Rs.29400
Mr.SCOTT is working as a ANALYST and getting Annual Salary Rs.36000
Mr.KING is working as a PRESIDENT and getting Annual Salary Rs.60000
Mr.TURNER is working as a SALESMAN and getting Annual Salary Rs.18000
Mr.ADAMS is working as a CLERK and getting Annual Salary Rs.13200
Mr.JAMES is working as a CLERK and getting Annual Salary Rs.11400
Mr.FORD is working as a ANALYST and getting Annual Salary Rs.36000
Mr.MILLER is working as a CLERK and getting Annual Salary Rs.15600

14 rows selected.

LTRIM() :
---------

-> Used to delete left side matching chars.

SQL> select ltrim('AAAARAMA','A') FROM DUAL;

LTRI
----
RAMA

Rtrim() :
---------

-> used to deletes right side matching characters

SQL> select Rtrim('RAMAAAAAAAAA','A') FROM DUAL;

RTR
---
RAM
TRIM() :
--------

-> it deletes bothsides matching characters

SQL> select trim('A' FROM 'AAAARAMAAAAAA') FROM DUAL;

TRI
---
RAM

SQL> SELECT * FROM EMP WHERE ENAME='ANAND';

no rows selected

SQL> SELECT * FROM EMP WHERE ENAME='ANAND ';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7788 ANAND ANALYST 7566 09-DEC-82 3000 20

SQL> SELECT * FROM EMP WHERE TRIM(ENAME)='ANAND';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7788 ANAND ANALYST 7566 09-DEC-82 3000 20

Note: By default trim function deletes spaces

-- waq to display middle name from given name

'RAMESH SACHIN TENDULKAR'

REPLACE() :
-----------

-> this function replaces word by word

SQL> select replace('AXIS BANK','AXIS','ICICI') FROM DUAL;

REPLACE('A
----------
ICICI BANK

SQL> SELECT REPLACE('JACK AND JUE','J','BL') FROM DUAL;

REPLACE('JACKA
--------------
BLACK AND BLUE

TRANSLATE() :
-------------

-> this function translates char. by char.


ex:-

SQL> select translate('president','p', ' ') from dual;

TRANSLATE
---------
resident

SUBSTRING() :
-------------

-> it returns sub-string from given string

ex:-

SQL> select substr('RAMA KRISHNA',6) FROM DUAL;

SUBSTR(
-------
KRISHNA

6 -> Substring displays from 6th position onwards.

ex2:-

SQL> select substr('RAMA KRISHNA',6,4) FROM DUAL;

SUBS
----
KRIS

6 -> Substring displays from 6th position onwards.

4 -> no.of occurances

ex3:-

SQL> select substr('RAMA KRISHNA', -7 ) FROM DUAL;

SUBSTR(
-------
KRISHNA

-7 -> substring position is counting from Right -> left, but output
displays Left -> Right

ex4:-

SQL> select * from emp where substr(job,1,3)='MAN';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7566 JONES MANAGER 7839 02-APR-81 2975 20
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10

SQL> SELECT 'MR.'||ENAME||' IS A ' || SUBSTR(JOB,1,3) ||' EATER.' FROM


EMP WHERE JOB='MANAGER';
'MR.'||ENAME||'ISA'||SUBSTR(JOB,1,3)||
--------------------------------------
MR.JONES IS A MAN EATER.
MR.BLAKE IS A MAN EATER.
MR.CLARK IS A MAN EATER.

INSTR() :
---------

-> This function returns Searching String Position

ex:-

SQL> Select INSTR( 'ORACLE CORPORATION', 'OR', 3, 2) FROM DUAL;

INSTR('ORACLECORPORATION','OR',3,2)
-----------------------------------
12

'OR' -> Searching String

3 -> Searching starting from 3rd position onwards

2 -> no.of times to be search

note: postion is counting from 1st char. onwards from left -> right(
fixed )

ex2:-

SQL> Select INSTR( 'ORACLE CORPORATION', 'OR', 3, 3) FROM DUAL;

INSTR('ORACLECORPORATION','OR',3,3)
-----------------------------------
0

'OR' -> Searching String

3 -> Searching starting from 3rd position onwards

3 -> no.of times to be search

note: postion is counting from 1st char. onwards from left -> right(
fixed )

ex3:-

SQL> Select INSTR( 'ORACLE CORPORATION', 'OR' ) FROM DUAL;

INSTR('ORACLECORPORATION','OR')
-----------------------------------
1

'OR' -> Searching String

-> by default INSTR function takes ( 1, 1 )

note: postion is counting from 1st char. onwards from left -> right(
fixed )
ex4:-

SQL> Select INSTR( 'ORACLE CORPORATION', 'OR', -1, 1 ) FROM DUAL;

INSTR('ORACLECORPORATION','OR',3,2)
-----------------------------------
12

'OR' -> Searching String

-1 -> Searching starting from 1st char. onwards from RIGHT -> LEFT

1 -> no.of times to be search

note: postion is counting from 1st char. onwards from left -> right(
fixed )

-- waq to display which employee names 'A' char. contains mininum 2 times

SQL> select ename , instr(ename,'A',1,2) from emp;

ENAME INSTR(ENAME,'A',1,2)
---------- --------------------
SMITH 0
ALLEN 0
WARD 0
JONES 0
MARTIN 0
BLAKE 0
CLARK 0
SCOTT 0
KING 0
TURNER 0
ADAMS 3
JAMES 0
FORD 0
MILLER 0

14 rows selected.

SQL> select ename , instr(ename,'A',1,2) from emp where


instr(ename,'A',1,2)>0;

ENAME INSTR(ENAME,'A',1,2)
---------- --------------------
ADAMS 3

ex:-

-- create a customer table and insert given data into table

cust_db: cid, cname, street, city

1,anand,'ameerpet hyderabad'
2,raj,'panjagutta hyderabad'
.
.
table creation:
---------------

create table cust_db( cid number(2), cname varchar(10), street


varchar(20), city varchar(20) );

select substr( 'ameerpet hyderabad', 1, Instr('ameerpet hyderabad','


',1,1) - 1 ) from dual;
-----------------------------------
9 - 1 => 10

SQL> select substr( 'ameerpet hyderabad', 1, Instr('ameerpet hyderabad','


',1,1) - 1 ) from dual;

SUBSTR('
--------
ameerpet

SQL> select substr( 'panjagutta hyderabad', 1, Instr('panjagutta


hyderabad',' ',1,1) - 1 ) from dual;

SUBSTR('PA
----------
panjagutta

To Display CITY Names :


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

select substr('ameerpet hyderabad', instr('ameerpet hyderabad',' ', -1


,1 ) +1 ) from dual;
----------------------------------
------
9 +1 => 10

SQL> select substr('ameerpet hyderabad', instr('ameerpet hyderabad',' ',


-1 ,1 ) +1 ) from dual;

SUBSTR('A
---------
hyderabad

SQL> desc cust_db;


Name Null? Type
----------------------------------------------------- -------- ---------
------------
CID NUMBER(2)
CNAME
VARCHAR2(10)
STREET
VARCHAR2(20)
CITY
VARCHAR2(20)

Inserting data into table :


***************************
Insert Into Cust_db values( 11, 'Anand', substr( 'ameerpet hyderabad',
1, Instr('ameerpet hyderabad',' ',1,1) - 1 ),
substr('ameerpet hyderabad',
instr('ameerpet hyderabad',' ', -1 ,1 ) +1 )
);

SQL> select * from cust_db;

CID CNAME STREET CITY


------ ---------- -------------------- --------------------
11 Anand ameerpet hyderabad

email-id:
---------

[email protected]
[email protected]
[email protected]

-- waq to display only USERNAME names

-- waq to display only DOMAIN names

select
substr('[email protected]',1,instr('[email protected]','@',1,1)-1)
from dual;
-----------------------------
----
5-1=4
1 - Substring position displays from 1st Char onwords up to 4 chars

SUBS
----
king

select substr('[email protected]',instr('[email protected]','@',-
1,1)+1) from dual;
-------------------------------
---
15+1=16
16 - Substring position displays from 16th char onwords

SUBSTR('KING@
--------------
rediffmail.com

-- waq to display middle name from given name

'RAMESH SACHIN TENDULKAR'

SQL> Select Ltrim('RAMESH SACHIN TENDULKAR','RAMESH') FROM DUAL;

LTRIM('RAMESHSACH
-----------------
SACHIN TENDULKAR

SQL> Select Rtrim( Ltrim('RAMESH SACHIN TENDULKAR','RAMESH'),


'TENDULKAR') FROM DUAL;

RTRIM(LT
--------
SACHIN

SQL> Select TRIM( Rtrim( Ltrim('RAMESH SACHIN TENDULKAR','RAMESH'),


'TENDULKAR') ) FROM DUAL;

TRIM(R
------
SACHIN

iii. DATE FUNCTIONS :


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

-> These functions are supports only DATE values

ex:-

SYSDATE :
---------

-> It returns current server date and time

ex:-

SQL> SELECT SYSDATE FROM DUAL;

SYSDATE
---------
18-AUG-23

ii. ADD_MONTHS() :
------------------

-> Used to add months to given date and it accepts + or -

SQL> select add_months(sysdate,2) from dual;

ADD_MONTH
---------
18-OCT-23

SQL> select add_months(sysdate,-2) from dual;

ADD_MONTH
---------
18-JUN-23

iii. MONTHS_BETWEEN() :
-----------------------
-> It returns months between two given dates

ex:-

SQL> select months_between(sysdate,'01-jan-2023' ) from dual;

MONTHS_BETWEEN(SYSDATE,'01-JAN-2023')
-------------------------------------
7.5757

iv. NEXT_DAY() :
----------------

-> returns comming week of the date

SQL> select next_day(sysdate, 'mon') from dual;

NEXT_DAY(
---------
21-AUG-23

SQL> select next_day(sysdate, 2) from dual;

NEXT_DAY(
---------
21-AUG-23

** by default oracle takes... sunday ... 1


monday ... 2
.
.
saturday...7

v. LAST_DAY() :
---------------

-> RETURNS last date of the month

SQL> select last_day(sysdate) from dual;

LAST_DAY(
---------
31-AUG-23

-- waq to display each employee experience in years

SQL> select empno, round( (sysdate - hiredate)/365 ) from emp;

EMPNO ROUND((SYSDATE-HIREDATE)/365)
------ -----------------------------
7369 43
7499 43
7521 43
7566 42
7654 42
7698 42
7782 42
7788 41
7839 42
7844 42
7876 41
7900 42
7902 42
7934 42

14 rows selected.

SQL> select empno, round( months_between(sysdate, hiredate )/12 ) from


emp;

EMPNO ROUND(MONTHS_BETWEEN(SYSDATE,HIREDATE)/12)
------ ------------------------------------------
7369 43
7499 42
7521 42
7566 42
7654 42
7698 42
7782 42
7788 41
7839 42
7844 42
7876 41
7900 42
7902 42
7934 42

14 rows selected.

-- waq to display next month first date

SQL> select last_day(sysdate) + 1 from dual;

LAST_DAY(
---------
01-SEP-23

-- waq to display current month first date

SQL> select add_months( last_day(sysdate), -1 ) +1 from dual;

ADD_MONTH
---------
01-AUG-23

-- waq to display current month 2nd & 4th saturday dates

2nd Saturday :
--------------

SQL> select next_day( add_months( last_day(sysdate), -1 ) + 7, 'sat')


from dual;

NEXT_DAY(
---------
12-AUG-23
4th Saturday :
--------------

SQL> select next_day( add_months( last_day(sysdate), -1 ) + 21, 'sat')


from dual;

NEXT_DAY(
---------
26-AUG-23

II. GROUP FUNCTIONS/AGGREGATE FUNCTIONS :


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

-> These functions can compare multiple values and return single value
output

-> Group functions are also called as Multi-row functions

ex:-

MIN() :
-------

-> this function returns min value from given list of values

SQL> select min(sal) from emp;

MIN(SAL)
--------
800

MAX() :
-------

-> this function returns maximum value

SQL> select max(sal) from emp;

MAX(SAL)
--------
5000

SUM() :
-------

-> returns total sum of salaries

SQL> SELECT SUM(SAL) FROM EMP;

SUM(SAL)
--------
29025

AVG() :
-------

-> It returns average value

SQL> select avg(sal) from emp;


AVG(SAL)
--------
2073.2

COUNT() :
---------

-> this function counts no.of values / records

ex:-

SQL> SELECT COUNT(EMPNO) FROM EMP;

COUNT(EMPNO)
------------
14

SQL> SELECT COUNT(COMM ) FROM EMP;

COUNT(COMM)
-----------
4

note: count function ignores NULLs

** to display with exact no.of records from the table...

SQL> select count(*) from emp;

COUNT(*)
--------
14

SQL> select count(1) from emp;

COUNT(1)
--------
14

SQL> select count(2) from emp;

COUNT(2)
--------
14

SQL> select sum(2) from emp;

SUM(2)
------
28

other examples :
----------------

-- waq to display min & max. salaries from emp table

SQL> select min(sal), max(sal) from emp;


MIN(SAL) MAX(SAL)
-------- --------
800 5000

-- waq to display senior most employee date of joining.

SQL> select min(hiredate) from emp;

MIN(HIRED
---------
17-DEC-80

-- to display latest employee details

SQL> select max(hiredate) from emp;

MAX(HIRED
---------
12-JAN-83

** what is output of the following queries

i. select max(ename) from emp;

MAX(ENAME)
----------
WARD

ii. select min(ename) from emp;

MIN(ENAME)
----------
ADAMS

iii. select sum(ename) from emp;

select sum(ename) from emp;


*

ERROR at line 1:
ORA-01722: invalid number

iv. select avg(job) from emp;

select avg(job) from emp;

*
ERROR at line 1:
ORA-01722: invalid number

ex:-

TABLENAME: table_a

ColumnName: column_1
12
9
0
null
null
1
8
0
null
9
null
7

i. select count(column_1) from table_a;

o/p: COUNT(COLUMN_1)
---------------
8

ii select count(*) from table_a;

o/p: COUNT(*)
--------
12

iii. select count( distinct(column_1)) from table_a;

o/p: COUNT(DISTINCT(COLUMN_1))
-------------------------
6

iv. select count( distinct(*)) from table_a;

o/p: select count( distinct(*)) from table_a;


*

ERROT at line 1:
ORA-00936 missing expression

** what is output of the following queries

i. select max(ename) from emp;

ans:- WARD

ii. select min(ename) from emp;

ex:- ADAMS

iii. select sum(ename) from emp;

ERROR: ORA-01722: invalid number

iv. select avg(job) from emp;

ans:- ORA-01722: invalid number


note: SUM & AVG functions are number values

TABLENAME: table_a

ColumnName: column_1
12
9
0
null
null
1
8
0
null
9
null
7

i. select count(column_1) from table_a;

o/p: 8

ii select count(*) from table_a;

o/p: 14

iii. select count( distinct(column_1)) from table_a;

o/p: 6

iv. select count( distinct(*)) from table_a;

o/p:

ERROR at line 1:
ORA-00936: missing expression

III. CONVERSION FUNCTIONS :


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

-> these functions can convert one datatype to another datatype


temporarily

-> There are 3 types of Conversion functions.

i. TO_CHAR()

ii. TO_NUMBER()

iii. TO_DATE()

i. TO_CHAR() :
----------------

-> This function converts any DATE / NUMBER values into CHARACTER
format temporarily

or
-> This function converts ORACLE PRE-DEFINED date format into USER
DEFINED Date format temporarily

EX: '21-aug-23' -> to_char() -> '21/08/23'

examples :
----------

SYSDATE : Returns current server date and time

ex:-

select sysdate from dual;

SQL> select sysdate from dual;

SYSDATE
---------
21-AUG-23

DATE FORMATS :
--------------

'd' -> returns day of the week

SQL> select to_char(sysdate, 'd' ) from dual;

T
-
2

note: by default oracle takes... sunday - 1, monday - 2, .... saturday -


7

-> day of the month

SQL> select to_char(sysdate, 'dd' ) from dual;

TO
--
21

'ddd' -> day of the year

SQL> select to_char(sysdate, 'ddd' ) from dual;

TO_
---
233

'dy' -> returns first three chars. of the day

SQL> select to_char(sysdate, 'dy' ) from dual;

TO_CHAR(SYSD
------------
mon

'day' -> returns fullform of the day

SQL> select to_char(sysdate, 'day' ) from dual;

TO_CHAR(SYSDATE,'DAY')
------------------------------------
monday

'w' -> week of the month

SQL> select to_char(sysdate, 'w' ) from dual;

T
-
3

'ww' -> week of the year

SQL> select to_char(sysdate, 'ww' ) from dual;

TO
--
34

'mm' -> month in numaric format

SQL> select to_char(sysdate, 'mm' ) from dual;

TO
--
08

'mon' -> first three chars. of the month

SQL> select to_char(sysdate, 'mon' ) from dual;

TO_CHAR(SYSD
------------
aug

'month' -> fullform of the month

SQL> select to_char(sysdate, 'month' ) from dual;

TO_CHAR(SYSDATE,'MONTH')
------------------------------------
august

'y' -> returns last digit of the year

'yy' -> returns last two digits of the year

'yyy' -> returns last three digits of the year

'yyyy' -> year in numaric format


SQL> select to_char(sysdate, 'y' ) from dual;

T
-
3

SQL> select to_char(sysdate, 'yy' ) from dual;

TO
--
23

SQL> select to_char(sysdate, 'yyy' ) from dual;

TO_
---
023

SQL> select to_char(sysdate, 'yyyy' ) from dual;

TO_C
----
2023

'year' -> year in char. format

SQL> select to_char(sysdate, 'year' ) from dual;

TO_CHAR(SYSDATE,'YEAR')
------------------------------------------
twenty twenty-three

'cc' -> current century

SQL> select to_char(sysdate, 'cc' ) from dual;

TO
--
21

'q' -> returns quarter of the year

SQL> select to_char(sysdate, 'q' ) from dual;

T
-
3

'ddth' -> returns day of the month in the following formats

ex:- 01st, 02nd, 03rd, etc.,

SQL> select to_char(sysdate, 'ddth' ) from dual;

TO_C
----
21st
'ddsp' -> day of the month in spelling format

SQL> select to_char(sysdate, 'ddsp' ) from dual;

TO_CHAR(SYSD
------------
twenty-one

'j' -> returns day in Julian Format

SQL> select to_char(sysdate, 'j' ) from dual;

TO_CHAR
-------
2460178

note: above 'j' returns no.of days from oracle starting date to till date

oracle starting date : 01-JAN-4712 B.C

orale end-date : 31-DEC-9999 A.D.

examples:-

-- waq to display SYSDATE in the following formats

i. 21/08/23

SQL> SELECT TO_CHAR( SYSDATE, 'DD/MM/YY') FROM DUAL;

TO_CHAR(
--------
21/08/23

ii. 21st aug, 2023

SQL> SELECT TO_CHAR( SYSDATE, 'ddth mon, yyyy.') FROM DUAL;

TO_CHAR(SYSDATE,'DDTHMON
------------------------
21st aug, 2023.

--> waq to display employee date of joinings in the following format

SQL> select empno, to_char(hiredate,'dd/mm/yyyy') from emp;

EMPNO TO_CHAR(HI
------ ----------
7369 17/12/1980
7499 20/02/1981
7521 22/02/1981
7566 02/04/1981
7654 28/09/1981
7698 01/05/1981
7782 09/06/1981
7788 09/12/1982
7839 17/11/1981
7844 08/09/1981
7876 12/01/1983
7900 03/12/1981
7902 03/12/1981
7934 23/01/1982

14 rows selected.

SQL> select empno, to_char(hiredate,'mm/dd/yyyy') from emp;

EMPNO TO_CHAR(HI
------ ----------
7369 12/17/1980
7499 02/20/1981
7521 02/22/1981
7566 04/02/1981
7654 09/28/1981
7698 05/01/1981
7782 06/09/1981
7788 12/09/1982
7839 11/17/1981
7844 09/08/1981
7876 01/12/1983
7900 12/03/1981
7902 12/03/1981
7934 01/23/1982

14 rows selected.

-- waq to display who are joined in 1981 year

SQL> select * from emp where to_char(hiredate, 'yyyy')=81;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20

10 rows selected.

-- waq to display who are joined in 1st quarter of the year

SQL> select * from emp where to_char(hiredate, 'q')=1;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

-- waq to display who joined last week from the current year
SQL> select * from emp where to_char(hiredate,'ww') =
to_char(sysdate,'ww') -1
and
to_char(hiredate,'yyyy' ) =
to_char(sysdate,'yyyy');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7788 SCOTT ANALYST 7566 15-AUG-23 3000 20

-- waq to display who are joined in current week of the current year

SQL> select * from emp where to_char(hiredate,'ww') =


to_char(sysdate,'ww')
and
to_char(hiredate,'yyyy' ) =
to_char(sysdate,'yyyy');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 21-AUG-23 3000 20

-- waq to display who are joined on MONDAY

SQL> select * from emp where to_char(hiredate,'d' ) = 2;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7902 FORD ANALYST 7566 21-AUG-23 3000 20

-- waq to display each employee total sum of salary upto last month.

select empno, months_between( add_months( last_day(sysdate), -1 ),


hiredate ) * sal from emp;

TO CONVERT NUMBER to CHAR Format :


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

-- waq to display each employee salary from the given format

5,000.00
6,000.00
.
.
.
4,500.00

SQL> select empno, to_char(sal,'99,999.99') from emp;

EMPNO TO_CHAR(SA
---------- ----------
7369 800.00
7499 1,600.00
7521 1,250.00
7566 2,975.00
7654 1,250.00
7698 2,850.00
7782 2,450.00
7788 3,000.00
7839 5,000.00
7844 1,500.00
7876 1,100.00
7900 950.00
7902 3,000.00
7934 1,300.00

14 rows selected.

-- to display amount with Rupees format

NUMBER FORMATS :
----------------

'L' -> returns local currency symbol

SQL> select empno, to_char(sal,'L99,999.99') from emp;

EMPNO TO_CHAR(SAL,'L99,999
---------- --------------------
7369 $800.00
7499 $1,600.00
7521 $1,250.00
7566 $2,975.00
7654 $1,250.00
7698 $2,850.00
7782 $2,450.00

'C' -> returns local currency name

SQL> select empno, to_char(sal,'C99,999.99') from emp;

EMPNO TO_CHAR(SAL,'C99,
---------- -----------------
7369 USD800.00
7499 USD1,600.00
7521 USD1,250.00
7566 USD2,975.00
7654 USD1,250.00
7698 USD2,850.00
7782 USD2,450.00

'S' -> returns sign symbol

SQL> select empno, to_char(sal,'S99,999.99') from emp;

EMPNO TO_CHAR(SA
---------- ----------
7369 +800.00
7499 +1,600.00
7521 +1,250.00
7566 +2,975.00
7654 +1,250.00
** To display currency with Indian Rupees

SQL> ALTER SESSION SET NLS_TERRITORY='INDIA';

Session altered.

SQL> select empno, to_char(sal,'L99,999.99') from emp;

EMPNO TO_CHAR(SAL,'L99,999
---------- --------------------
7369 Rs800.00
7499 Rs1,600.00
7521 Rs1,250.00
7566 Rs2,975.00
7654 Rs1,250.00
7698 Rs2,850.00
7782 Rs2,450.00
7788 Rs3,000.00
7839 Rs5,000.00
7844 Rs1,500.00
7876 Rs1,100.00
7900 Rs950.00
7902 Rs3,000.00
7934 Rs1,300.00

14 rows selected.

SQL> select empno, to_char(sal,'C99,999.99') from emp;

EMPNO TO_CHAR(SAL,'C99,
---------- -----------------
7369 INR800.00
7499 INR1,600.00
7521 INR1,250.00
7566 INR2,975.00
7654 INR1,250.00
7698 INR2,850.00
7782 INR2,450.00
7788 INR3,000.00
7839 INR5,000.00
7844 INR1,500.00
7876 INR1,100.00
7900 INR950.00
7902 INR3,000.00
7934 INR1,300.00

14 rows selected.

SQL> select empno, to_char(sal,'S99,999.99') from emp;

EMPNO TO_CHAR(SA
---------- ----------
7369 +800.00
7499 +1,600.00
7521 +1,250.00
7566 +2,975.00
7654 +1,250.00
7698 +2,850.00
7782 +2,450.00
7788 +3,000.00
7839 +5,000.00
7844 +1,500.00
7876 +1,100.00
7900 +950.00
7902 +3,000.00
7934 +1,300.00

14 rows selected.

SQL> ALTER SESSION SET NLS_TERRITORY='JAPAN';

Session altered.

SQL> select empno, to_char(sal,'L99,999.99') from emp;

EMPNO TO_CHAR(SAL,'L99,999
---------- --------------------
7369 Ñ800.00
7499 Ñ1,600.00
7521 Ñ1,250.00
7566 Ñ2,975.00
7654 Ñ1,250.00
7698 Ñ2,850.00
7782 Ñ2,450.00
7788 Ñ3,000.00
7839 Ñ5,000.00
7844 Ñ1,500.00
7876 Ñ1,100.00
7900 Ñ950.00
7902 Ñ3,000.00
7934 Ñ1,300.00

14 rows selected.

SQL> select empno, to_char(sal,'C99,999.99') from emp;

EMPNO TO_CHAR(SAL,'C99,
---------- -----------------
7369 JPY800.00
7499 JPY1,600.00
7521 JPY1,250.00
7566 JPY2,975.00
7654 JPY1,250.00
7698 JPY2,850.00
7782 JPY2,450.00
7788 JPY3,000.00
7839 JPY5,000.00
7844 JPY1,500.00
7876 JPY1,100.00
7900 JPY950.00
7902 JPY3,000.00
7934 JPY1,300.00

14 rows selected.

SQL> SELECT SYSDATE FROM DUAL;

SYSDATE
--------
23-08-22

SQL> ALTER SESSION SET NLS_TERRITORY='INDIA';

Session altered.

SQL> SELECT SYSDATE FROM DUAL;

SYSDATE
--------
22-08-23

II. TO_DATE() :
---------------

-> This function converts any USER DEFINED DATE format into ORACLE
DEFAULT DATE Format

input:- 22/08/23 -> TO_DATE() -> 22-AUG-23

ex:-

SQL> select to_date( '22/08/23', 'dd/mm/yy') from dual;

TO_DATE('
---------
22-AUG-23

ex2:-

SQL> select to_date( '2023/08/22', 'yyyy/mm/dd') from dual;

TO_DATE('
---------
22-AUG-23

note:-

TO_CHAR() : to convert ORACLE PRE-DEFINED Date format into USER_DEFINED


DATE format

ex: '22-aug-23' -> 22/08/23

TO_DATE() : to convert USER-DEFINED DATE format into ORACLE PRE-DEFINED


DATE Format

ex: '22/08/23' -> '22-AUG-23'

III. TO_NUMBER() :
------------------

-> this function convert CHAR. NUMBER values into NUMBER format
temporarily

ex:-
-- to find sum of two given numbers

'1,234.57' , '789.78'

SQL> select '1,234.57' + '789.78' from dual;


select '1,234.57' + '789.78' from dual
*
ERROR at line 1:
ORA-01722: invalid number

ex:-

SQL> select to_number( '1,234.57', '9,999.99') + to_number( '789.89',


'999.99') from dual;

TO_NUMBER('1,234.57','9,999.99')+TO_NUMBER('789.89','999.99')
-------------------------------------------------------------
2024.46

IV. GENERAL FUNCTIONS :


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

-> these functions are supports any datatypes

ex:-

GREATEST() :
------------

-> it returns greatest value from given list of values

SQL> select greatest(10,20,30,40) from dual;

GREATEST(10,20,30,40)
---------------------
40

** differences between GREATEST & MAX functions ?

GREATEST : it is a multi argument function

MAX : it is single argument function

ex:-

SQL> select max(10,20,30,40) from dual;


select max(10,20,30,40) from dual
*
ERROR at line 1:
ORA-00909: invalid number of arguments

LEAST() :
---------

-> returns least value from given list of values


ex:-

SQL> select least('d','cd','bcd','abcd') from dual;

LEAS
----
abcd

UID :
------

-> returns User Identification Number

SQL> select uid from dual;

UID
----------
48

USER :
------

-> returns currently connected user name

SQL> select user from dual;

USER
------------------------------
ORA8PM

DISTINCT() :
------------

-> this function eliminates duplicate values

SQL> select distinct(job) from emp;

JOB
---------
CLERK
SALESMAN
PRESIDENT
MANAGER
ANALYST

SQL> select distinct(DEPTNO) from emp;

DEPTNO
----------
30
20
10

NVL() :
-------

-> used to perform arithmetic operations by using NULLs

Syn:-
NVL(expr1,expr2) :
******************

-> if Expr1 is null then Expr2 is evaluated otherwise Expr1 output

ex:-

SQL> select nvl(NULL,100), NVL(500,1000) FROM DUAL;

NVL(NULL,100) NVL(500,1000)
------------- -------------
100 500

** write a query to display each employee netsalary

netsalary := SAL + COMM

SQL> SELECT 100+NULL, 500-NULL, 1000*NULL, 200/NULL FROM DUAL;

100+NULL 500-NULL 1000*NULL 200/NULL


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

SQL> SELECT EMPNO, SAL, COMM, SAL + COMM FROM EMP;

EMPNO SAL COMM SAL+COMM


---------- ---------- ---------- ----------
7369 800
7499 1600 300 1900
7521 1250 500 1750
7566 2975
7654 1250 1400 2650
7698 2850
7782 2450
7788 3000
7839 5000
7844 1500 0 1500
7876 1100
7900 950
7902 3000
7934 1300

14 rows selected.

SQL> SELECT EMPNO, SAL, NVL( COMM,0), SAL + NVL(COMM,0) FROM EMP;

EMPNO SAL NVL(COMM,0) SAL+NVL(COMM,0)


---------- ---------- ----------- ---------------
7369 800 0 800
7499 1600 300 1900
7521 1250 500 1750
7566 2975 0 2975
7654 1250 1400 2650
7698 2850 0 2850
7782 2450 0 2450
7788 3000 0 3000
7839 5000 0 5000
7844 1500 0 1500
7876 1100 0 1100
7900 950 0 950
7902 3000 0 3000
7934 1300 0 1300

14 rows selected.

SOUNDEX() :
-----------

-> this function used to compares the data based on given pronounsation

ex:-

-- waq to display Smith Employee Record

SQL> select * from emp where ename='smit';

no rows selected

SQL> select * from emp where ename='smith';

no rows selected

SQL> select * from emp where


soundex(ename)=soundex('ssssssssssssssmith');

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 800
20

SQL> select * from emp where soundex(ename)=soundex('smit');

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 800
20

SQL> select * from emp where soundex(ename)=soundex('allonneeee');

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30

SELECT statement rules :


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

rule 1:
-------
-- In SELECT statement selected columns all are ordinary columns then,
it executs successfully.

ex: select deptno, sal from emp;


------, ----
14 14

rule 2:
-------

-> In SELECT statement all are GROUP / AGGREGATE functions then It


executes successfully

ex: select min(sal), max(sal) from emp;


--------, --------
1 1
rule 3:
-------

-> In SELECT statement, selected columns should be return EQUAL no.of


values/records otherwise it returns ERROR message

ex: select deptno, max(sal) from emp;


-------,--------
14 , 1

select deptno, max(sal) from emp


*
ERROR at line 1:
ORA-00937: not a single-group group function

NOTE: In Select ALL Ordinary column / Group functions then Query


executed, otherwise it returns error message

Syntax of SELECT statement :


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

SELECT * / Column_list from <table_name>


[ Where <condition>/
GROUP BY Clause/
HAVING Clause /
ORDER BY Clause ];

WHERE Clause :
--------------

-> used to filter the data

-> WHERE clause compares ORDINARY Column values

-> if WHERE clause TRUE then SELECT statement executed

Syntax:-
--------

WHERE <column_name> <operator> <expression/value>;


Ex:-

SELECT * FROM EMP;

SELECT * FROM EMP WHERE DEPTNO=10;

SELECT * FROM EMP WHERE (SAL*12)>=60000;

GROUP BY Clause :
-----------------

-> To group the rows on specified columns

-> Whenever an ordinary column retrieved along with group function then
all ordinary columns must be
placed after GROUP BY clause

ex:-

-- waq to display dept.wise MAX of salaries

select deptno, MAX(sal) from emp GROUP BY Deptno;

DEPTNO SAL
---------- ----------
10 2450
10 5000
10 1300

20 2975
20 3000
20 1100
20 800
20 3000

30 1250
30 1500
30 1600
30 950
30 2850
30 1250

14 rows selected.

SQL> select deptno, MAX(sal) from emp GROUP BY Deptno;

DEPTNO MAX(SAL)
---------- ----------
30 2850
20 3000
10 5000

Ex:-

-- waq to display dept.wise SUM of salaries

SQL> SELECT DEPTNO, SUM(SAL) FROM EMP GROUP BY DEPTNO;

DEPTNO SUM(SAL)
---------- ----------
30 9400
20 10875
10 8750

-- Waq to display in each JOB min & max. salaries

SQL> SELECT JOB, MIN(SAL), MAX(SAL) FROM EMP GROUP BY JOB;

JOB MIN(SAL) MAX(SAL)


--------- ---------- ----------
CLERK 800 1300
SALESMAN 1250 1600
PRESIDENT 5000 5000
MANAGER 2450 2975
ANALYST 3000 3000

-- WAQ to display in each dept. howmany employees are working

SQL> select deptno, count(*) from emp group by deptno;

DEPTNO COUNT(*)
---------- ----------
30 6
20 5
10 3

-- waq to display dept.wise with job wise no.of employees are working

10 clerk 1
10 manager 1
.
.
20 clerk 1
20 manager 2
.
.

SQL> SELECT DEPTNO, JOB, COUNT(*) FROM EMP GROUP BY DEPTNO, JOB ORDER BY
DEPTNO;

DEPTNO JOB COUNT(*)


---------- --------- ----------
10 CLERK 1
10 MANAGER 1
10 PRESIDENT 1
20 ANALYST 2
20 CLERK 2
20 MANAGER 1
30 CLERK 1
30 MANAGER 1
30 SALESMAN 4

9 rows selected.

Ex:-

EMP_ATTEN:
----------
EMPID ATTEN_DATE STATUS
E1 01-AUG-23 P
E2 01-AUG-23 P
E3 01-AUG-23 A
E1 02-AUG-23 P
E2 02-AUG-23 A
E3 02-AUG-23 P
E1 03-AUG-23 P
.
.
.
.

-- waq to display each employee howmany days present in the current month

-- waq to display each employee howmany days absent in the current month

-- waq to display each employee howmany days taking leave in the current
month

-- waq to display total no.of working days in the current month

HAVING <condition> :
--------------------

-> Used to check GROUPED Column values / Group function results

-> After Group by clause it is valid

ex:-

-- waq to display in which JOBs min. salary morethan rs.2000

SQL> select job, min(sal) from emp group by job having min(sal) >2000;

JOB MIN(SAL)
--------- ----------
PRESIDENT 5000
MANAGER 2450
ANALYST 3000

-- waq to display in which dept. morethan 3 employees are working

SQL> select deptno, count(*) from emp group by deptno having count(*) >
3;

DEPTNO COUNT(*)
---------- ----------
30 6
20 5

ORDER BY CLAUSE :
-----------------
-> It will arrange SELECT output with ORDERED Format either
ASCENDING/DECENDING Order

-> By Default ORDER BY Clause displays ASCENDING Order

-> Only SELECT statement supports ORDER BY Clause

-> ORDER BY Clause must be placed at the end of SELECT statement

ex:-

SQL> SELECT * FROM EMP ORDER BY DEPTNO ASC;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7566 JONES MANAGER 7839 02-APR-81 2975
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7369 SMITH CLERK 7902 17-DEC-80 800
20
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7900 JAMES CLERK 7698 03-DEC-81 950
30
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30

14 rows selected.

SQL> SELECT * FROM EMP ORDER BY DEPTNO DESC;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7900 JAMES CLERK 7698 03-DEC-81 950
30
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7566 JONES MANAGER 7839 02-APR-81 2975
20
7369 SMITH CLERK 7902 17-DEC-80 800
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7782 CLARK MANAGER 7839 09-JUN-81 2450
10

14 rows selected.

SQL> SELECT * FROM EMP ORDER BY DEPTNO, ENAME;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7566 JONES MANAGER 7839 02-APR-81 2975
20
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7369 SMITH CLERK 7902 17-DEC-80 800
20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7900 JAMES CLERK 7698 03-DEC-81 950
30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30

14 rows selected.

NOTE: IN order by clause maximum 32 columns are supported

SQL> SELECT * FROM EMP ORDER BY 3;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7900 JAMES CLERK 7698 03-DEC-81 950
30
7369 SMITH CLERK 7902 17-DEC-80 800
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7566 JONES MANAGER 7839 02-APR-81 2975
20
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30

14 rows selected.

3 -> position of column in EMP table

Ex:-

EMP_ATTEN:
----------

EMPID ATTEN_DATE STATUS


E1 01-AUG-23 P
E2 01-AUG-23 P
E3 01-AUG-23 A
E1 02-AUG-23 P
E2 02-AUG-23 A
E3 02-AUG-23 P
E1 03-AUG-23 P
.
.
.
.

-- waq to display each employee howmany days present in the current month

Select Empid, Count(*) as No_of_Presents from Emp_Atten Where


Status='p'
and
to_char(atten_date,'mm-
yyyy') = to_char(sysdate,'mm-yyyy')
Group by Empid
Order by Empid;

-- waq to display each employee howmany days absent in the current month

-- waq to display each employee howmany days taking leave in the current
month

-- waq to display total no.of working days in the current month

HAVING <condition> :
--------------------

-> Used to check GROUPED Column values / Group function results

-> After Group by clause it is valid

ex:-

-- waq to display in which JOBs min. salary morethan rs.2000

SQL> select job, min(sal) from emp group by job having min(sal) >2000;

JOB MIN(SAL)
--------- ----------
PRESIDENT 5000
MANAGER 2450
ANALYST 3000

-- waq to display in which dept. morethan 3 employees are working

SQL> select deptno, count(*) from emp group by deptno having count(*) >
3;

DEPTNO COUNT(*)
---------- ----------
30 6
20 5

ORDER BY CLAUSE :
-----------------
-> It will arrange SELECT output with ORDERED Format either
ASCENDING/DECENDING Order

-> By Default ORDER BY Clause displays ASCENDING Order

-> Only SELECT statement supports ORDER BY Clause

-> ORDER BY Clause must be placed at the end of SELECT statement

ex:-

SQL> SELECT * FROM EMP ORDER BY DEPTNO ASC;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7566 JONES MANAGER 7839 02-APR-81 2975
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7369 SMITH CLERK 7902 17-DEC-80 800
20
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7900 JAMES CLERK 7698 03-DEC-81 950
30
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30

14 rows selected.

SQL> SELECT * FROM EMP ORDER BY DEPTNO DESC;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7900 JAMES CLERK 7698 03-DEC-81 950
30
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7566 JONES MANAGER 7839 02-APR-81 2975
20
7369 SMITH CLERK 7902 17-DEC-80 800
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7782 CLARK MANAGER 7839 09-JUN-81 2450
10

14 rows selected.

SQL> SELECT * FROM EMP ORDER BY DEPTNO, ENAME;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7566 JONES MANAGER 7839 02-APR-81 2975
20
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7369 SMITH CLERK 7902 17-DEC-80 800
20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7900 JAMES CLERK 7698 03-DEC-81 950
30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30

14 rows selected.

NOTE: IN order by clause maximum 32 columns are supported

SQL> SELECT * FROM EMP ORDER BY 3;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7900 JAMES CLERK 7698 03-DEC-81 950
30
7369 SMITH CLERK 7902 17-DEC-80 800
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7566 JONES MANAGER 7839 02-APR-81 2975
20
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7844 TURNER SALESMAN 7698 08-SEP-81 1500
0 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250
1400 30
7521 WARD SALESMAN 7698 22-FEB-81 1250
500 30
7499 ALLEN SALESMAN 7698 20-FEB-81 1600
300 30

14 rows selected.

3 -> position of column in EMP table

Syntax of SELECT statement :


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

SELECT * / Column_list from <table_name>


[ Where <condition>/
GROUP BY Clause/
HAVING Clause /
ORDER BY Clause ];

** What is the order of execution of SELECT statement :


*******************************************************
i. FROM

ii. WHERE

iii. GROUP BY

iv. HAVING

v. SELECT

vi. ORDER BY

Create a New table :


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

Cust_db:- Cid, Cname, Mobileno, email_id, address

-> cid should not be allow duplicates

-> cid value is compulsory

CONSTRAINTS :
-------------

-> Constraint is a pre-defined rule, that rule is applied on DB Columns


at the time of table creation or
After Table Creation

-> Constraints are activated whenever DML operations are performed

-> Constraints are also activated when the tables are manipulated by
other Users or by Other application s/w tools

TYPES OF CONSTRAINTS :
----------------------

-> Oracle supports 6 types of Constraints

I. NOT NULL Constraint

II. UNIQUE Constraint

III. CHECK Constraint

IV. DEFAULT Constraint

V. PRIMARY KEY Constraint

VI. FOREIGN KEY Constraint(REFERENCES)

-> To add a constraint to morethan one COLUMN is called as Composite


Constraints

Ex:- UNIQUE( PID, CID )

-> if Table contains PRIMARY KEY constraints that table is called as


MASTER TABLE / PARENT TABLE / INDEPENDENT TABLE
-> if Table contains FOREIGN KEY constraint that table is called as
TRANSACTION TABLE / CHILD TABLE / DEPENDENT TABLE

-> Constraints are not supported if any COLUMN contains UN-STRUCTURED


datatypes(ex: lob, blob, clob, raw, long raw, varray,

bfile, etc.,)

** To add a constraint to db columns there are 3 methods:


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

i. column level :
-----------------

-> Constraints are added to next to column name at the time table
creation

syn:- Create table <table_name>( col1 datatype(size)


[constraint <constraint_name>]
<constraint_type>,
col2 datatype(size)
[constraint <constraint_name>]
<constraint_type>,
.
.
);

ii. TABLE LEVEL :


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

-> Constraints are added after declaring all columns at the time of
table creation

syn:- Create table <table_name>( col1 datatype(size),


col2 datatype(size),
.
.,
[Constraint <constraint_name>]
<constraint_type>( col1 [, col2,...] )
);

iii. ALTER Level :


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

-> After Table creation to add constraints to db columns

syn:- ALTER TABLE <table_name> ADD/MODIFY Constraint


<constraint_name>( col1 [, col2,...] );

I. NOT NULL Constraint :


------------------------
-> This constraint doesn't accept NULLs

-> If any column value is Mandatory/Compulsory then NOT NULL supported

-> but, NOT NULL constraint accepts DUPLICATEs

ex:-

-- Create a Employee db table with empid, ename, Salary & deptno

validations :
-------------

-> empid column value is compulsory

-> Employee Name is mandatory

Create Table Emp_db( eid number(4) Constraint ABC NOT NULL,


ename varchar2(10) Constraint XYZ NOT NULL,
sal number(8,2),
dno number(2)
);

I. NOT NULL Constraint :


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

-> This constraint doesn't accept NULLs

-> If any column value is Mandatory/Compulsory then NOT NULL supported

-> but, NOT NULL constraint accepts DUPLICATEs

ex:-

-- Create a Employee db table with empid, ename, Salary & deptno

validations :
-------------

-> empid column value is compulsory

-> Employee Name is mandatory

Create Table Emp_db( eid number(4) Constraint Emp_db_eid_nn NOT NULL,


ename varchar2(10) Constraint Emp_db_ename_nn NOT NULL,
sal number(8,2),
dno number(2)
);

Testing:
--------

SQL> Insert Into Emp_db values( 1001, 'Anand', 5000, 10 );

1 row created.
SQL> Insert Into Emp_db values( 1002, 'Srinu', 4000, 20 );

1 row created.

SQL> Insert Into Emp_db values( NULL, 'Allen', 6000, 30 );


Insert Into Emp_db values( NULL, 'Allen', 6000, 30 )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ORA8PM"."EMP_DB"."EID")

SQL>
SQL> Insert Into Emp_db values( 1003, NULL, 6000, 30 );
Insert Into Emp_db values( 1003, NULL, 6000, 30 )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ORA8PM"."EMP_DB"."ENAME")

SQL> SELECT * FROM EMP_DB;

EID ENAME SAL DNO


------ ---------- ------ ------
1001 Anand 5000 10
1002 Srinu 4000 20

SQL> Insert Into Emp_db values( 1002, 'Allen', 6000, 30 ); --


Duplicate values allows

1 row created.

SQL> SELECT * FROM EMP_DB;

EID ENAME SAL DNO


------ ---------- ------ ------
1001 Anand 5000 10
1002 Srinu 4000 20
1002 Allen 6000 30

II. UNIQUE Constraint :


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

-> This constraint Avoids duplicate values

-> Once UNIQUE constraint is added automaticaly INDEX db object(


implicit index ) added automatically

-> Index is used to improves the performance while retrieving or


manipulating data

-> Unique Constraint accepts NULLs

ex:-

-- Create a customer db table with customer id, customer name, mobileno


and address

validations :
-------------
-> Customer id column should not be allow duplicate values

Table creation :
----------------

Create table Cust_DB( Cid Varchar(10)


Constraint cust_db_cid_UN UNIQUE,
Cname varchar(20),
MobileNo Number(10),
Mail_id varchar2(20)
);

testing :
---------

SQL> Insert Into cust_db values( 'c1', 'King', 9000994005,


'[email protected]');

1 row created.

SQL> Insert Into cust_db values( 'c1', 'Scott', 9000994006,


'[email protected]');
Insert Into cust_db values( 'c1', 'Scott', 9000994006, '[email protected]')
*
ERROR at line 1:
ORA-00001: unique constraint (ORA8PM.CUST_DB_CID_UN) violated

SQL> Insert Into cust_db values( null, 'Scott', 9000994006,


'[email protected]');

1 row created.

SQL> Insert Into cust_db values( null, 'Smith', 9000994007,


'[email protected]');

1 row created.

SQL> select * from cust_db;

CID CNAME MOBILENO MAIL_ID


---------- -------------------- ---------- --------------------
c1 King 9000994005 [email protected]
Scott 9000994006 [email protected]
Smith 9000994007 [email protected]

How to Add TWO different constraints to a single column :


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

ex:-

ex:-

-- Create a customer db table with customer id, customer name, mobileno


and address

validations :
-------------

-> Customer id column value is mandatory ( NOT NULL )

-> Customer id column should not be allow duplicate values ( UNIQUE )

Table creation :
----------------

Create Table Cust_db( cid varchar(10)


Constraint Cust_db_cid_nn NOT NULL
Constraint cust_db_cid_un UNIQUE,
cname varchar(20),
mobileno number(10),
mail_id varchar(20)
);

or

Create Table Cust_db( cid varchar(10)


Constraint Cust_db_cid_nn_un NOT NULL UNIQUE,
cname varchar(20),
mobileno number(10),
mail_id varchar(20)
);

testing :
---------

Table created.

SQL> Insert into Cust_db values( 'c1', 'king', 9000994005,


'[email protected]');

1 row created.

SQL> Insert into Cust_db values( null, 'scott', 9000994006,


'[email protected]');
Insert into Cust_db values( null, 'scott', 9000994006, '[email protected]')
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ORA8PM"."CUST_DB"."CID")

SQL> Insert into Cust_db values( 'c1', 'scott', 9000994006,


'[email protected]');
Insert into Cust_db values( 'c1', 'scott', 9000994006, '[email protected]')
*
ERROR at line 1:
ORA-00001: unique constraint (ORA8PM.CUST_DB_CID_UN) violated

SQL> select * from cust_db;

CID CNAME MOBILENO MAIL_ID


---------- -------------------- ---------- --------------------
c1 king 9000994005 [email protected]
III. CHECK constraint :
-----------------------

-> This constraint main functionality if given check condition is TRUE


then record INSERTED otherwise it returns error message.

Ex:-

-- create a student db table with student id, student name, class,


maths, phys, chem

validations :
-------------

-> class should be accepts only ix, x

-> maximum marks of Maths, Phys & Chem is 100

Table creation :
----------------

Create table stud_db( sid varchar(10),


sname varchar(20),
class varchar(10)
Constraint stud_db_class_chk CHECK( class in (
'ix','x') ),
maths number(5,2)
Constraint stud_db_maths_chk CHECK( Maths <=100 ),
Phys number(5,2)
Constraint stud_db_phys_chk CHECK( Phys <=100 ),
Chem Number(5,2)
Constraint stud_db_Chem_chk CHECK( Chem <=100 )
);

Testing :
---------

SQL> Insert into stud_db values( 's1', 'king', 'ix', 89, 78, 98 );

1 row created.

SQL> Insert into stud_db values( 's2', 'Nath', 'x', 67, 89, 68 );

1 row created.

SQL> Insert into stud_db values( 's3', 'Eswar', 'xi', 67, 89, 68 );
Insert into stud_db values( 's3', 'Eswar', 'xi', 67, 89, 68 )
*
ERROR at line 1:
ORA-02290: check constraint (ORA8PM.STUD_DB_CLASS_CHK) violated

SQL> Insert into stud_db values( 's3', 'Eswar', 'x', 102, 89, 68 );
Insert into stud_db values( 's3', 'Eswar', 'x', 102, 89, 68 )
*
ERROR at line 1:
ORA-02290: check constraint (ORA8PM.STUD_DB_MATHS_CHK) violated

SQL> Insert into stud_db values( 's3', 'Eswar', 'x', 92, 105, 68 );
Insert into stud_db values( 's3', 'Eswar', 'x', 92, 105, 68 )
*
ERROR at line 1:
ORA-02290: check constraint (ORA8PM.STUD_DB_PHYS_CHK) violated

SQL> Insert into stud_db values( 's3', 'Eswar', 'x', 92, 95, 101 );
Insert into stud_db values( 's3', 'Eswar', 'x', 92, 95, 101 )
*
ERROR at line 1:
ORA-02290: check constraint (ORA8PM.STUD_DB_CHEM_CHK) violated

SQL> select * from stud_db;

SID SNAME CLASS MATHS PHYS


CHEM
---------- -------------------- ---------- ---------- ---------- --------
--
s1 king ix 89 78
98
s2 Nath x 67 89
68

CHECK Constraint Examples :


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

validations :
*************

-> Account type should be accept either 's' or 'c'

-> Mobileno accepts only 10 digits

-> Minimum opening balance rs.1000/-

bal number(7,2) check ( bal >=1000 )

-> mail id should be contains '@' symbol

-> min. length of password is 8 chars

-> password should be start with an ALPHABET

IV. DEFAULT Constraint :


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

-> this constraint is used to take specified default value

-> if any column value is fixed then to use DEFAULT Constraint

ex:-
-- create a student db table with stud id, stud name, class, date of
joining, fee

validations :
-------------

-> date of joining will take today date automatically

-> All student fee structure is rs.10000/-

table creation :
----------------

Create table stud_db( std_id varchar(10),


std_name varchar(20),
class varchar(10),
doj date default sysdate,
fee number(8,2) default 10000
);

Testing :
---------

SQL> Insert into stud_db values( '101', 'ABCD', 'IX' );


Insert into stud_db values( '101', 'ABCD', 'IX' )
*
ERROR at line 1:
ORA-00947: not enough values

SQL> Insert into stud_db values( '101', 'ABCD', 'IX', DEFAULT, DEFAULT );

1 row created.

SQL> insert into stud_db ( std_id, std_name, class ) values( '102','XYZ',


'IX' );

1 row created.

SQL> SELECT * FROM STUD_DB;

STD_ID STD_NAME CLASS DOJ FEE


---------- -------------------- ---------- --------- ------
101 ABCD IX 28-AUG-23 10000
102 XYZ IX 28-AUG-23 10000

V. PRIMARY KEY Constraint(UNIQUE + NOT NULL + INDEX ) :


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

-> It is one of the ORACLE Integrity constraint

-> It is a combination of two contraints that is UNIQUE & NOT NULL

-> Once add PRIMARY KEY constraint by default INDEX also added, that is
IMPLICIT INDEX

-> This constraint doesn't allow NULLs


-> It is avoids duplicate values

-> if table contains PRIMARY KEY constraints that table is called as


MASTER TABLE / PARENT TABLE /
INDEPENDENT TABLE

-> In column level only one column supported PRIMARY KEY Constraint

-> Primary key constraint is not supported if any column datatyep


contains UN-STRUCTURED Datatypes

ex:-

-- create a dept. master table with dept. id, dept.name & loc

validations :
-------------

-> dept. id should not be allow duplicates

-> dept. id value should be unique

-> dept. name is mandatory

-> dept. loc is mandatory

table creation :
----------------

Create table dept_mas( deptid number(4)


constraint dept_mas_dept_id_PK PRIMARY KEY,
deptname varchar(20)
constraint dept_mas_deptname_nn NOT NULL,
loc varchar(20)
constraint dept_mas_LOC_nn NOT NULL
);

testing :
---------

SQL> Insert into dept_mas values( 10, 'acc', 'hyd' );

1 row created.

SQL> Insert into dept_mas values( 20, 'res', 'sec' );

1 row created.

SQL> Insert into dept_mas values( 30, 'fin', 'chennai' );

1 row created.

SQL> Insert into dept_mas values( 40, 'admin', 'banglore' );

1 row created.

SQL> Insert into dept_mas values( 40, 'sales', 'banglore' );


Insert into dept_mas values( 40, 'sales', 'banglore' )
*
ERROR at line 1:
ORA-00001: unique constraint (ORA8PM.DEPT_MAS_DEPT_ID_PK) violated

SQL> Insert into dept_mas values( null, 'sales', 'banglore' );


Insert into dept_mas values( null, 'sales', 'banglore' )
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ORA8PM"."DEPT_MAS"."DEPTID")

SQL> select * from dept_mas;

DEPTID DEPTNAME LOC


------ -------------------- --------------------
10 acc hyd
20 res sec
30 fin chennai
40 admin banglore

EMPLOYEE :
----------

EMPID ENAME SAL DEPTID(fk) REFERENCES DEPT_MAS(DEPTID)


1 XXX 4000 10
2 XXX 3000 20
3 XXX 5000 50 x
60
70

VI. FOREIGN KEY Constraint ( REFERENCES ) :


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

-> this constraint is used to establish relationship between two tables


of columns or same table of columns

-> To Add Foreign key constraint other table column( REFERENCED TABLE)
COLUMN ( REFERENCED Column ) should be
contain PRIMARY KEY or UNIQUE constraint

-> To add Foreign key constraint to morethan one column that type
constraint is called as COMPOSITE FOREIGN KEY Constraint

-> if Table contains FOREIGN KEY Constraints that table is called as


TRANSACTION TABLE / CHILD TABLE / DEPENDENT TABLE

-> Foreign key constraint accepts DUPLICATES & NULLs

-> Foreign key constraint is not supported if any column contains un-
structured datatypes

Ex:-

-- Create a employee table with Employee id, Employee name, Salary &
deptid
Validations :
-------------

-> Recruting Employee Deptid should be available in the Organisation

Table Creation :
----------------

Create table employee( empid number(10),


ename varchar2(20),
sal number(8,2),
deptid number(2)
Constraint Employee_Deptid_fk REFERENCES
dept_mas(Deptid)
);

Testing :
---------

SQL> Insert Into employee values ( 1001, 'king', 5000, 10 );

1 row created.

SQL> Insert Into employee values ( 1002, 'scott', 4000, 20 );

1 row created.

SQL> Insert Into employee values ( 1003, 'smith', 5000, 10 );

1 row created.

SQL> Insert Into employee values ( 1004, 'allen', 3000, 50 );


Insert Into employee values ( 1004, 'allen', 3000, 50 )
*
ERROR at line 1:
ORA-02291: integrity constraint (ORA8PM.EMPLOYEE_DEPTID_FK) violated -
parent key not found

SQL> Insert Into employee values ( 1004, 'allen', 2500, 30 );

1 row created.

SQL> Insert Into employee values ( 1005, 'james', 5500, 20 );

1 row created.

SQL> Insert Into employee values ( 1006, 'jones', 4500, 10 );

1 row created.

SQL> commit;

Commit complete.

SQL> select * from dept_mas;

DEPTID DEPTNAME LOC


------ -------------------- --------------------
10 acc hyd
20 res sec
30 fin chennai
40 admin banglore

SQL> select * from employee;

EMPID ENAME SAL DEPTID


------ -------------------- ------ ------
1001 king 5000 10
1002 scott 4000 20
1003 smith 5000 10
1004 allen 2500 30
1005 james 5500 20
1006 jones 4500 10

6 rows selected.

example 2:-
-----------

stud_db: std_id(pk), std_name, class

stud_marks: std_id(fk), maths, phys, chem

stud_grade: std_id(fk), total, avge, grade

PRIMARY KEY Table :


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

Create table std_db( std_id varchar(10)


constraint std_db_std_id_pk PRIMARY KEY,
std_name varchar(20),
std_class varchar(20)
);

FOREIGN KEY Table :


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

Create Table std_marks( std_id varchar(10)


Constraint std_db_std_id_FK REFERENCES std_db(
std_id ),
Maths number(8,2),
Phys number(8,2),
Chem number(8,2)
);

Create table std_grade( std_id varchar(10)


Constraint std_db_std_id_FK REFERENCES
std_db(std_id),
Total number(8,2),
Avge Number(8,2),
Grade Varchar(10)
);
e_commerce application :
-----------------------

Item_mas : item_id(pk), item_name, price

cust_mas : cid(pk), cname, mobileno, mail_id, address

Order_db : ord_id(pk), ord_date, item_id(fk), cid(fk), DoD, Qty, Tamt

** We can't delete parent record if any child records are found.

ex:-

SQL> DELETE FROM DEPT_MAS WHERE DEPTID=10;


DELETE FROM DEPT_MAS WHERE DEPTID=10
*
ERROR at line 1:
ORA-02292: integrity constraint (ORA8PM.EMPLOYEE_DEPTID_FK) violated -
child record found

DELETING RULES :
---------------

ON DELETE CASCADE :
-------------------

-> This option is used to whenever parent record deleted then


corresponding child records will delete
automatically

-> This option will be added at the time of FOREIGN KEY declaration

ex:-

Table Creation :
----------------

Create table employee( empid number(10),


ename varchar2(20),
sal number(8,2),
deptid number(2)
Constraint Employee_Deptid_fk REFERENCES
dept_mas(Deptid) ON DELETE CASCADE
);

** If foreign key table already created

ex:-

step1 : drop foreign key on employee(deptid)

SQL> alter table employee drop constraint employee_deptid_fk;

Table altered.
step2: Add foreign key constraint on employee(deptid) with ON DELETE
CASCADE OPTION

SQL> Alter table employee ADD Constraint employee_deptid_fk


Foreign key(deptid) References Dept_mas(Deptid) ON
DELETE CASCADE;

Table altered.

Testing :
---------

SQL> SELECT * FROM DEPT_MAS;

DEPTID DEPTNAME LOC


------ -------------------- --------------------
10 acc hyd
20 res sec
30 fin chennai
40 admin banglore

SQL> SELECT * FROM EMPLOYEE;

EMPID ENAME SAL DEPTID


------ -------------------- ------ ------
1001 king 5000 10
1002 scott 4000 20
1003 smith 5000 10
1004 allen 2500 30
1005 james 5500 20
1006 jones 4500 10

6 rows selected.

SQL> DELETE FROM DEPT_MAS WHERE DEPTID=20;

1 row deleted.

SQL> SELECT * FROM DEPT_MAS;

DEPTID DEPTNAME LOC


------ -------------------- --------------------
10 acc hyd
30 fin chennai
40 admin banglore

SQL> SELECT * FROM EMPLOYEE;

EMPID ENAME SAL DEPTID


------ -------------------- ------ ------
1001 king 5000 10
1003 smith 5000 10
1004 allen 2500 30
1006 jones 4500 10

ii. ON DELETE SET NULL :


------------------------
-> this option used to whenever PARENT record deleted then
CORRESPONDING child record column values set to NULLs

-> This option also will be added at the time of FOREIGN KEY
declaration

note: Same steps followed by above ON DELETE CASCADE option example

-> here we are following 2nd method

** If foreign key table already created

ex:-

step1 : drop foreign key on employee(deptid)

SQL> alter table employee drop constraint employee_deptid_fk;

Table altered.

step2: Add foreign key constraint on employee(deptid) with ON DELETE


CASCADE OPTION

SQL> Alter table employee ADD Constraint employee_deptid_fk


Foreign key(deptid) References Dept_mas(Deptid) ON
DELETE CASCADE;

Table altered.

Testing :
---------

SQL> SELECT *FROM DEPT_MAS;

DEPTID DEPTNAME LOC


------ -------------------- --------------------
10 acc hyd
30 fin chennai
40 admin banglore

SQL> SELECT * FROM EMPLOYEE;

EMPID ENAME SAL DEPTID


------ -------------------- ------ ------
1001 king 5000 10
1003 smith 5000 10
1004 allen 2500 30
1006 jones 4500 10

SQL> DELETE FROM DEPT_MAS WHERE DEPTID=10;

1 row deleted.

SQL> SELECT *FROM DEPT_MAS;

DEPTID DEPTNAME LOC


------ -------------------- --------------------
30 fin chennai
40 admin banglore

SQL> SELECT * FROM EMPLOYEE;

EMPID ENAME SAL DEPTID


------ -------------------- ------ ------
1001 king 5000
1003 smith 5000
1004 allen 2500 30
1006 jones 4500

COMPOSITE Constraints :
-----------------------

-> To Add a constraint to morethan one column is called as composite


constraints

syn:- unique( col1, col2 )

-> In composite constraints maximum 32 columns are added

-> In composite constrains data is comparing with PAIRWISE

ex:-

i. composite PRIMARY KEY :


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

-> Primary Key constraint is added to morethan one column is called as


Composite Primary Key constraint

ex:-

-- Create a prod master table with Company Id, Prod Id, Prod Name

validations :
-------------

-> Comp Id and Prod Ids are mandatory

-> Comp Id and Prod Ids pair should not be repeat

ex:-

TABLE LEVEL Method :


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

Create table prod_mas( cid varchar(10),


pid varchar(10),
pname varchar(20),
constraint prod_mas_cid_pid_pk Primary Key(cid, pid ) );

Insert Into prod_mas values( &cid, &pid, &pname );

prod:
-----
cid pid pname
---- ---- ------
c1 p1 tea
c1 p2 coffee
c2 p1 tea
c1 p1 soaps -- invalid

Composite FOREIN KEY Constraint :


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

-> Foreign key constraint is added to morethan one column is called as


composite foreign constraint

ex:-

-- create a sales with sales id, sales date, cid, pid, qty, amt

validations :
--------------

-> selling cid, pids pair should be matched with PROD( cid, pid )

ex:-

sales :

sid sdate cid pid qty amt


s1 xxx c1 p1 2 1000
s2 xxx c2 p2 1 500 -- invalid error message

COMPOSITE Constraints :
-----------------------

-> To Add a constraint to morethan one column is called as composite


constraints

syn:- unique( col1, col2 )

-> In composite constraints maximum 32 columns are added

-> In composite constrains data is comparing with PAIRWISE

ex:-

i. composite PRIMARY KEY :


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

-> Primary Key constraint is added to morethan one column is called as


Composite Primary Key constraint

ex:-

-- Create a prod master table with Company Id, Prod Id, Prod Name

validations :
-------------

-> Comp Id and Prod Ids are mandatory


-> Comp Id and Prod Ids pair should not be repeat

ex:-

TABLE LEVEL Method :


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

Create table prod_mas( cid varchar(10),


pid varchar(10),
pname varchar(20),
constraint prod_mas_cid_pid_pk Primary Key(cid, pid ) );

Insert Into prod_mas values( &cid, &pid, &pname );

prod:
-----
cid pid pname
---- ---- ------
c1 p1 tea
c1 p2 coffee
c2 p1 tea
c1 p1 soaps -- invalid

ex2:-

std_db:
-------

std_mas: std_id, std_name, class

validation:
-----------

-> std_id , Class pair mandatory and should not be allow duplicate

std_mas: std_id, std_name, class


s1 king x
s2 scott ix
s2 allen x
s1 smith x -- invalid

Composite FOREIN KEY Constraint :


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

-> Foreign key constraint is added to morethan one column is called as


composite foreign constraint

ex:-

-- create a sales with sales id, sales date, cid, pid, qty, amt

validations :
--------------

-> selling cid, pids pair should be matched with PROD( cid, pid )

ex:-
prod:
-----
cid pid pname
---- ---- ------
c1 p1 tea
c1 p2 coffee
c2 p1 tea
c1 p1 soaps -- invalid

sales :

sid sdate cid pid qty amt


s1 xxx c1 p1 2 1000
s2 xxx c2 p2 1 500 -- invalid error message

Table creation :
----------------

Create table sales( sid varchar(10),


sdat date,
cid varchar(10),
pid varchar(10),
qty number(2),
amt number(8,2),
Constraint sales_cid_pid_fk Foreign key(cid, pid )
REFERENCES Prod( cid, pid )
);

Composite CHECK constraint :


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

-> To add CHECK constraint to morethan one column is called as


composite check CONSTRAINT

Ex:-

-- create a employee db table with empid, ename, sal & comm

validations:
------------

-> employee salary + comm should not be exceeds rs.10000/-

table creation :
----------------

create table emp_db( empid number(10),


ename varchar(20),
sal number(8,2),
comm number(6,2),
constraint emp_db_sal_comm_chk CHECK ( SAL +
NVL(COMM,0) <=10000 ) )
);

EMP_DB
------
empid ename sal comm
1 kkk 5000 2000
2 mmm 6000 4000
3 xxx 8000 3000 -- returns error message

ex2:-

-- create a medicine table with medicine id, medicine name, date of


manfactured and date of expired date

validations :
-------------

-> Medicine expired date should be > Manifactured date

How to add constraints in ALTER LEVEL :


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

-> After table creation to add constraints to existing db columns by


using ALTER command

ex:-

UNIQUE :
--------

Alter table emp_db ADD constraint emp_db_empid_un UNIQUE(empid);

NOT NULL :
----------

Alter table emp_db MODIFY Ename Constraint emp_db_ename_nn NOT NULL;

DEFAULT :
---------

Alter table emp_db MODIFY DOJ Default Sysdate;

CHECK :-
--------

Alter table emp_db ADD constraint emp_db_sal_chk CHECK ( SAL >=5000 );

** how to enable / disable constraints**


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

-> by default all constraints are ENABLED, to disable a constraint..

Alter table Emp_db DISABLE Constraint emp_db_empid_un;


---------
ENABLE

** how to drop a constraint :


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

ALTER Table emp_db drop constraint EMP_DB_EMPID_UN;

Example :
---------

-- create a CUST_MASTER table with customer id, customer name, address,


mobileno and mail id

validations:
------------

-> customer id is mandatory and it should not be allow duplicates

-> mobileno should allow only 10 digits

-- create a BANK_MASTER table with account no, customer no, date of


opening, account type and balance

validations :
-------------

-- account no is mandatory and should not be allow duplicates

-- Inserting customer id should be available in customer master table

-- date of opening is system date

-- account type should be accepts either 's' or 'c'

-- Mini. opening balance rs.500/-

-- create a BANK_TRANS with acccount no, customer no, trans. date,


trans.type and trans. amount

validations :
-------------

-- Inserting customer id should be available in customer master table

-- Inserting Account no. should be available in bank master table

-- trans. date is system date ( today date )

-- trans. type should be accepts either 'd' or 'w'

-- Mini. trans. amount rs.1/-

SUB-QUERIES :
-------------

--> What is a query ?

-> Query means to requesting data from DB tables

-> Queries are classified into 3 types

i. ROOT QUERY

ii. PARENT QUERY


iii. CHILD QUERY

i. ROOT QUERY :
---------------

-> the query which is not depends upon another query output for it's
conditional value

ex:- select * from emp;

ii. PARENT QUERY :


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

-> The query which is depends upon another query output for it's
conditional value

-> Parent query is also called as OUTER QUERY / DEPENDENT QUERY

ex:- SELECT * FROM EMP WHERE SAL = ( SELECT MAX(SAL) FROM EMP );
------------------------------
Parent query

iii. CHILD QUERY :


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

-> The query which returns output to it's parent's query is called as
CHILD QUERY

-> Child query is also called as SUB-QUERY / NESTED QUERY / INNER


QUERY / INDEPENDENT QUERY

Ex:- SELECT * FROM EMP WHERE SAL = ( SELECT MAX(SAL) FROM EMP
);
------------------------------
Child query

SUB-QUERIES :
-------------

-> Query within a query is called as Sub-query

-> Sub-queries are supported by SELECT, UPDATE, INSERT, DELETE


statements

-> Sub-queries are placed in WHERE clause of SELECT, UPDATE and DELETE
statements

-> Sub-queries are also placed in FROM clause and COLUMN_LIST of Outer
Query

-> If Sub-queries are placed in FROM Clause that type of queries are
called as IN-LINE sub-queries / IN-LINE Views

syn:- SELECT * FROM ( sub-query );

-> If sub-queries are placed in COLUMN_LIST of outer query is called


as SCALAR SUB-QUERIES
syn:- SELECT COL1, COL2,...( sub-query ), col3 from
<table_name>;

Restrictions :
--------------

-> Sub-queries must be placed in with in the Brackets ( )

-> Sub-queries are not supported by ORDER BY Clause, only IN-LINE SUB-
QUERIES are supported

-> Maximum 255 sub-queries can be nested

Adv. :
------

-> by using sub-queries, It improves the performance while retrieving


or manipulating data

TYPES of SUB-QUERIES :
----------------------

-> ORACLE supports 5 types of SUB-QUERIES

I. SINGLE ROW / SIMPLE SUB-QUERIES

II. MULTI-ROW SUB-QUERIES

III. MULTI-COLUMN SUB-QUERIES

IV. CO-RELATED SUB-QUERIES

V. SCALAR SUB-QUERIES

-> In Single Row / Multi-Row / Multi-column sub-queries, First SUB-QUERY


is executed depends upon output of sub-query
the Parent Query will be Executed.

ex:- SELECT * FROM EMP WHERE SAL = ( SELECT MAX(SAL) FROM EMP
);

I. SINGLE ROW SUB-QUERIES :


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

-> Sub-query returns single value is called as single row sub-queries

-> In single row sub-queries, Sub-query outputs are compared with >, <,
>=, <=, =, BETWEEN, NOT BETWEEN, etc., operators

ex:-

-- waq to display SMITH employee and his Coleagues

SQL> SELECT DEPTNO FROM EMP WHERE ENAME='SMITH';

DEPTNO
------
20

SQL> SELECT ENAME FROM EMP WHERE DEPTNO=20;

ENAME
----------
SMITH
JONES
SCOTT
ADAMS
FORD

Sub-query :
-----------

SQL> SELECT ENAME FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM EMP WHERE
ENAME='SMITH');

ENAME
----------
SMITH
JONES
SCOTT
ADAMS
FORD

-- waq to display maximum salary employee details

SQL> select * from emp where sal = ( select max(sal) from emp);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7839 KING PRESIDENT 17-NOV-81 5000 10

-- waq to display who are joined after joining of FORD employee

SQL> SELECT * FROM EMP WHERE HIREDATE > ( select hiredate from emp where
ename='FORD');

--waq to display who are getting morethan SCOTT employee salary

SQL> SELECT * FROM EMP WHERE SAL > ( select sal from emp where
ename='SCOTT');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7839 KING PRESIDENT 17-NOV-81 5000 10

-- waq to display latest employee joining details

-- waq to display senior most employee record

-- waq to display 2nd maximum salary

-- waq to display 3rd maximum salary


-- waq to display who are getting morthan CLERK salaries

I. SINGLE ROW SUB-QUERIES :


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

-> Sub-query returns single value is called as single row sub-queries

-> In single row sub-queries, Sub-query outputs are compared with >, <,
>=, <=, =, BETWEEN, NOT BETWEEN, etc., operators

ex:-

-- waq to display SMITH employee and his Coleagues

SQL> SELECT DEPTNO FROM EMP WHERE ENAME='SMITH';

DEPTNO
------
20

SQL> SELECT ENAME FROM EMP WHERE DEPTNO=20;

ENAME
----------
SMITH
JONES
SCOTT
ADAMS
FORD

Sub-query :
-----------

SQL> SELECT ENAME FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM EMP WHERE
ENAME='SMITH');

ENAME
----------
SMITH
JONES
SCOTT
ADAMS
FORD

-- waq to display maximum salary employee details

SQL> select * from emp where sal = ( select max(sal) from emp);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7839 KING PRESIDENT 17-NOV-81 5000 10

-- waq to display who are joined after joining of FORD employee

SQL> SELECT * FROM EMP WHERE HIREDATE > ( select hiredate from emp where
ename='FORD');

--waq to display who are getting morethan SCOTT employee salary


SQL> SELECT * FROM EMP WHERE SAL > ( select sal from emp where
ename='SCOTT');

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7839 KING PRESIDENT 17-NOV-81 5000 10

-- waq to display latest employee joining details

SQL> select * from emp where hiredate = ( select max(hiredate) from emp
);

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7902 FORD ANALYST 7566 21-AUG-23 3000
20

-- waq to display senior most employee record

SQL> select * from emp where hiredate = ( select min(hiredate) from emp
);

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 800
20

-- waq to display 2nd maximum salary

SQL> select max(sal) from emp where sal < ( select max(sal) from emp );

MAX(SAL)
----------
3000

-- waq to display 3rd maximum salary

SQL> select max(sal) from emp where sal< ( select max(sal) from emp where
sal < ( select max(sal) from emp ) );

MAX(SAL)
----------
2975

-- waq to display who are getting morthan CLERK salaries

SELECT * FROM EMP WHERE SAL >(select max(sal) from emp where
job='CLERK');

-- waq to find SMITH employee BOSS ( Superior )

SQL> select ename from emp where empno=( select mgr from emp where
ename='SMITH');
ENAME
----------
FORD

-- WAQ to display who are working in NEW YORK location

SQL> SELECT * FROM EMP WHERE DEPTNO=( select deptno from dept where
loc='NEW YORK' );

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7934 MILLER CLERK 7782 23-JAN-82 1300
10

-- waq to display who are working in RESEARCH dept.

-- waq to display who are working in SALES & ACCOUNTING dept.

-- waq to display who are joined 1981 in SALES dept.

II. MULTI-ROW Sub-Queries :


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

-> Sub-query returns morethan one value is called as Multi-row sub-


query

-> In Multi-row sub-queries, sub-query outputs are compared with


special operators those are IN, ANY, ALL & EXISTS operators

ex:-

-- waq to display who are working in NEW YORK and DALLAS Locations

SQL> SELECT * FROM EMP WHERE DEPTNO = ( select deptno from dept where loc
IN ( 'NEW YORK', 'DALLAS' ) );
SELECT * FROM EMP WHERE DEPTNO = ( select deptno from dept where loc IN (
'NEW YORK', 'DALLAS' ) )
*
ERROR at line 1:
ORA-01427: single-row subquery returns more than one row

SQL> SELECT * FROM EMP WHERE DEPTNO IN ( select deptno from dept where
loc IN ( 'NEW YORK', 'DALLAS' ) );

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7934 MILLER CLERK 7782 23-JAN-82 1300
10
7839 KING PRESIDENT 17-NOV-81 5000
10
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7876 ADAMS CLERK 7788 12-JAN-83 1100
20
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7566 JONES MANAGER 7839 02-APR-81 2975
20
7369 SMITH CLERK 7902 17-DEC-80 800
20

8 rows selected.

-- WAQ to display who are getting morethan ALL SALESMAN salaries

SQL> select sal from emp where job='SALESMAN';

SAL
----------
1600
1250
1250
1500

SQL> SELECT * FROM EMP WHERE SAL >ALL ( select sal from emp where
job='SALESMAN' );

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450
10
7698 BLAKE MANAGER 7839 01-MAY-81 2850
30
7566 JONES MANAGER 7839 02-APR-81 2975
20
7788 SCOTT ANALYST 7566 15-AUG-23 3000
20
7902 FORD ANALYST 7566 21-AUG-23 3000
20
7839 KING PRESIDENT 17-NOV-81 5000
10

6 rows selected.

-- Waq to display who are getting lessthan any MANAGERs salaries

SELECT * FROM EMP WHERE SAL < ANY ( select sal from emp where
job='MANAGER');

EXISTS :
--------
-> This operator returns BOOLEAN value

-> if sub-query executed successfully and it returns atleast one record


then EXISTS returns TRUE

-> if sub-query executed successfully but, it returns no rows selected


then EXISTS returns FALSE

Ex:-

-- waq if any employees working in 20th dept. then to increment all


employee salaries with 50%

SQL> Update emp set sal = sal + sal * 0.5 WHERE EXISTS (select * from emp
where deptno=20);

14 rows updated.

SQL> Update emp set sal = sal + sal * 0.5 WHERE EXISTS (select * from emp
where deptno=50);

0 rows updated.

-- waq to display only Superior Names

-- waq to display only EMPLOYEE Names

III. MULTI-COLUMN Sub-queries :


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

-> Sub-query returns morethan one column is called as Multi-column sub-


query

-> In Multi-column sub-queries, No.of columns return by Sub-query


should be matched with No.of columns in
WHERE clause of OUTER QUERY and corresponding columns datatypes
shouldbe same.

syn:- select * from <table_name> WHERE ( col1, col2 ) IN (


select col1, col2 from <table_name>);

-> In multi-column sub-queries data is camparing with PAIRWISE

-> Multi-column sub-queries is also called as PAIR-WISE Sub-queries

III. MULTI-COLUMN Sub-queries :


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

-> Sub-query returns morethan one column is called as Multi-column sub-


query

-> In Multi-column sub-queries, No.of columns return by Sub-query


should be matched with No.of columns in
WHERE clause of OUTER QUERY and corresponding columns datatypes
shouldbe same.
syn:- select * from <table_name> WHERE ( col1, col2 ) IN (
select col1, col2 from <table_name>);

-> In multi-column sub-queries data is camparing with PAIRWISE

-> Multi-column sub-queries is also called as PAIR-WISE Sub-queries

ex:-

-- waq to display dept.wise maximum salary employee details

SQL> SELECT * FROM EMP WHERE ( DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL)
FROM EMP GROUP BY DEPTNO);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7788 SCOTT ANALYST 7566 15-AUG-23 4500 20
7839 KING PRESIDENT 17-NOV-81 7500 10

-- waq to display dept.wise BOSSES ( Superiors )

SQL> select ename from emp where ( empno, deptno ) in ( select mgr,
deptno from emp);

ENAME
----------
FORD
BLAKE
KING
JONES
SCOTT
CLARK

6 rows selected.

IV. CO-RELATED SUB-QUERIES :


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

-> In this Queries, first OUTER QUERY is executed, depends upon output
of OUTER QUERY the INNER QUERY will be executed.

-> if Outer query executes 'n' times then Inner Query also Executes 'n'
times

-> One of the Outer Query column is placed in Sub-query WHERE


condition, that outer query column is called as co-related column

syn:- select col1, col2,... from <table_name> WHERE col2=( select


col3 from <table_name>
WHERE < col3 =
col2 > );

EMP_DB
------
EMPNO SAL DEPTNO
7369 3000 20 x
7566 5000 30
7839 6000 10
7521 2000 30 x
7499 4000 10 x
7788 8000 20

Ex:-

-- waq to display who are getting morethan their DEPT. Avg. Salaries

7839 6000 10
Select e.empno, e.sal, e.deptno from emp e 5000
where e.sal > ( select avg(sal) from emp
6000 where deptno =
e.deptno );
10

10 - 5000
20 - 5500
30 - 3500

SQL> Select e.empno, e.sal, e.deptno from emp e


where e.sal > ( select avg(sal)
from emp
where
deptno = e.deptno );

EMPNO SAL DEPTNO


------ ------ ------
7499 2400 30
7566 4462.5 20
7698 4275 30
7788 4500 20
7839 7500 10
7902 4500 20

6 rows selected.

SQL> select deptno, avg(sal) from emp group by deptno;

DEPTNO AVG(SAL)
------ --------
30 2350
20 3262.5
10 4375

-- waq to display who are getting lessthan their jobs Maximum salaries

SQL> select e.empno, e.ename, e.job, e.sal, e.deptno from emp e


where e.sal < ( select
max(sal) from emp where job=e.job );

EMPNO ENAME JOB SAL DEPTNO


------ ---------- --------- ------ ------
7369 SMITH CLERK 1200 20
7521 WARD SALESMAN 1875 30
7654 MARTIN SALESMAN 1875 30
7698 BLAKE MANAGER 4275 30
7782 CLARK MANAGER 3675 10
7844 TURNER SALESMAN 2250 30
7876 ADAMS CLERK 1650 20
7900 JAMES CLERK 1425 30

8 rows selected.

using EXISTS operator :


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

-- waq to display working employee DEPT. details

40 OPERATIONS BOSTON
SELECT D.DEPTNO, D.DNAME, D.LOC FROM DEPT D
WHERE EXISTS ( SELECT * FROM EMP WHERE
DEPTNO = D.DEPTNO );
40

SQL> SELECT D.DEPTNO, D.DNAME, D.LOC FROM DEPT D


WHERE EXISTS ( SELECT *
FROM EMP WHERE DEPTNO = D.DEPTNO );

DEPTNO DNAME LOC


------ -------------- -------------
20 RESEARCH DALLAS
30 SALES CHICAGO
10 ACCOUNTING NEW YORK

-- Waq to display in which DEPTS. no employee are working

SQL> SELECT D.DEPTNO, D.DNAME, D.LOC FROM DEPT D


WHERE NOT EXISTS ( SELECT
* FROM EMP WHERE DEPTNO = D.DEPTNO );

DEPTNO DNAME LOC


------ -------------- -------------
40 OPERATIONS BOSTON

V. SCALAR Sub-Queries :
-----------------------

-> Sub-queries are placed in COLUMN_LIST of OUTER QUERY is called as


Scalar Sub-Query

-> In Scalar sub-queries, sub-query should be return Single column and


Single Value

ex:-

-- waq to display employee details with all employees Sum of salaries

SQL> select empno, ename, job, sal, deptno, ( select sum(sal) from emp )
as total_sal from emp;

EMPNO ENAME JOB SAL DEPTNO TOTAL_SAL


------ ---------- --------- ------ ------ ---------
7369 SMITH CLERK 1200 20 43538
7499 ALLEN SALESMAN 2400 30 43538
7521 WARD SALESMAN 1875 30 43538
7566 JONES MANAGER 4462.5 20 43538
7654 MARTIN SALESMAN 1875 30 43538
7698 BLAKE MANAGER 4275 30 43538
7782 CLARK MANAGER 3675 10 43538
7788 SCOTT ANALYST 4500 20 43538
7839 KING PRESIDENT 7500 10 43538
7844 TURNER SALESMAN 2250 30 43538
7876 ADAMS CLERK 1650 20 43538
7900 JAMES CLERK 1425 30 43538
7902 FORD ANALYST 4500 20 43538
7934 MILLER CLERK 1950 10 43538

14 rows selected.

V. SCALAR Sub-Queries :
-----------------------

-> Sub-queries are placed in COLUMN_LIST of OUTER QUERY is called as


Scalar Sub-Query

-> In Scalar sub-queries, sub-query should be return Single column and


Single Value

syn:- select col1, col2,... ( sub-query ), col4, .... from


<table_name>;

ex:-

-- waq to display employee details with all employees Sum of salaries

SQL> select empno, ename, job, sal, deptno, ( select sum(sal) from emp )
as total_sal from emp;

EMPNO ENAME JOB SAL DEPTNO TOTAL_SAL


------ ---------- --------- ------ ------ ---------
7369 SMITH CLERK 1200 20 43538
7499 ALLEN SALESMAN 2400 30 43538
7521 WARD SALESMAN 1875 30 43538
7566 JONES MANAGER 4462.5 20 43538
7654 MARTIN SALESMAN 1875 30 43538
7698 BLAKE MANAGER 4275 30 43538
7782 CLARK MANAGER 3675 10 43538
7788 SCOTT ANALYST 4500 20 43538
7839 KING PRESIDENT 7500 10 43538
7844 TURNER SALESMAN 2250 30 43538
7876 ADAMS CLERK 1650 20 43538
7900 JAMES CLERK 1425 30 43538
7902 FORD ANALYST 4500 20 43538
7934 MILLER CLERK 1950 10 43538

14 rows selected.

-- waq to display employee details and corresponding each employee


dept.wise sum of salaries
Select e.empno, e.ename, e.job, e.sal, e.deptno, ( select sum(sal) from
emp where deptno=e.deptno) as dept_sumsal
from emp e;

EMPNO ENAME JOB SAL DEPTNO DEPT_SUMSAL


------ ---------- --------- ------ ------ -----------
7369 SMITH CLERK 1200 20 16313
7499 ALLEN SALESMAN 2400 30 14100
7521 WARD SALESMAN 1875 30 14100
7566 JONES MANAGER 4462.5 20 16313
7654 MARTIN SALESMAN 1875 30 14100
7698 BLAKE MANAGER 4275 30 14100
7782 CLARK MANAGER 3675 10 13125
7788 SCOTT ANALYST 4500 20 16313
7839 KING PRESIDENT 7500 10 13125
7844 TURNER SALESMAN 2250 30 14100
7876 ADAMS CLERK 1650 20 16313
7900 JAMES CLERK 1425 30 14100
7902 FORD ANALYST 4500 20 16313
7934 MILLER CLERK 1950 10 13125

14 rows selected.

-- waq to display dept. details and corresponding dept.wise min. and max.
salararies

SQL> Select d.deptno, d.dname, d.loc, ( select nvl( min(sal),0 ) from emp
where deptno=d.deptno) as minsal,
( select nvl( max(sal),0 ) from emp
where deptno=d.deptno) as maxsal
from dept d;

DEPTNO DNAME LOC MINSAL MAXSAL


------ -------------- ------------- ------ ------
10 ACCOUNTING NEW YORK 1950 7500
20 RESEARCH DALLAS 1200 4500
30 SALES CHICAGO 1425 4275
40 OPERATIONS BOSTON 0 0

-- waq to display dept.wise sum of salaries with Percentages

SQL> select deptno, SUM(SAL), sum(sal) / (select sum(sal) from emp ) *


100 as PCT from emp group by deptno;

DEPTNO SUM(SAL) PCT


------ -------- ------
30 14100 32.386
20 16313 37.468
10 13125 30.146

Ex:-

emp_db: eno, ename, sal, deptno


101
102
.
.

emp_atten: eno, adate, atype


101 1st sep p
102 1st sep a
101 2nd sep p
102 2nd sep p
.
.

queries :
---------

-- waq to display employee details( eno, ename ) and corresponding each


employee no.of days paresent

-- waq to display employee details( eno, ename ) and corresponding each


employee no.of days absent

-- waq to display employee details( eno, ename ) and corresponding each


employee no.of days leave

NESTED SELECT :
---------------

-> SELECT with in the SELECT is called as NESTED select

ex:-

-- waq to display No.of emps, No.of depts & No.of Grades

sql> select ( select count(*) from emp ) as no_of_emps,


( select count(*) from dept) as no_of_depts,
( select count(*) from salgrade) as no_of_grades
from dual;

NO_OF_EMPS NO_OF_DEPTS NO_OF_GRADES


---------- ----------- ------------
14 4 5

SET OPERATORS :
---------------

-> SET OPERATORS are used to join the OUTPUTs of SELECT statements

syn:- select * from <table_name>


<set_operator>
select * from <TABLE_NAME>;

-> SELECT statements should be contain EQUAL no.of COLUMNs and


corresponding columns datatypes should be same.

-> In first select STATEMENT only ORDER BY supported

TYPES OF SET OPERATORS :


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

I. UNION ALL
II. UNION

III. INTERSECT

IV. MINUS

I. UNION ALL :
--------------

-> By using this operator, it displays All records from QUERY1 and
QUERY2

ex:-

SQL> select job from emp where deptno=10;

JOB
---------
MANAGER
PRESIDENT
CLERK

SQL> select job from emp where deptno=20;

JOB
---------
CLERK
MANAGER
ANALYST
CLERK
ANALYST

SQL> select job from emp where deptno=10


UNION ALL
select job from emp where deptno=20;

JOB
---------
MANAGER
PRESIDENT
CLERK
CLERK
MANAGER
ANALYST
CLERK
ANALYST

8 rows selected.

ii. UNION :
-----------

-> It displays matching records from Query1 and Query2 at one time and
Un-Matched records from Both Queries

SQL> select job from emp where deptno=10;

JOB
---------
MANAGER
PRESIDENT
CLERK

SQL> select job from emp where deptno=20;

JOB
---------
CLERK
MANAGER
ANALYST
CLERK
ANALYST

SQL> select job from emp where deptno=10


UNION
select job from emp where deptno=20;

JOB
---------
ANALYST
CLERK
MANAGER
PRESIDENT

iii. INTERSECT :
----------------

-> It displays matching records from Query1 and Query2 at one time

ex:-

SQL> select job from emp where deptno=10;

JOB
---------
MANAGER
PRESIDENT
CLERK

SQL> select job from emp where deptno=20;

JOB
---------
CLERK
MANAGER
ANALYST
CLERK
ANALYST

SQL> select job from emp where deptno=10


INTERSECT
select job from emp where deptno=20;

JOB
---------
CLERK
MANAGER
IV. MINUS :
-----------

--> It displays un-matched records from Query1 compare to Query2

ex:-

A = { 1, 2, 4, 6 }

B = { 2, 3, 5, }

A - B = { 1, 4, 6 }

ex:-

SQL> select job from emp where deptno=10;

JOB
---------
MANAGER
PRESIDENT
CLERK

SQL> select job from emp where deptno=20;

JOB
---------
CLERK
MANAGER
ANALYST
CLERK
ANALYST

SQL> select job from emp where deptno=10


MINUS
select job from emp where deptno=20;

O/P:
-----

PRESIDENT

-- waq to dept.wise and job. wise min. and max. salaries

SQL> SELECT DEPTNO, NULL, MIN(SAL), MAX(SAL) FROM EMP GROUP BY DEPTNO
UNION ALL
SELECT NULL, JOB, MIN(SAL), MAX(SAL) FROM EMP GROUP BY JOB;

DEPTNO NULL MIN(SAL) MAX(SAL)


------ --------- -------- --------
30 1425 4275
20 1200 4500
10 1950 7500
CLERK 1200 1950
SALESMAN 1875 2400
PRESIDENT 7500 7500
MANAGER 3675 4462.5
ANALYST 4500 4500

8 rows selected.

-- waq to display min. and max. salary emloyee details

SQL> select * from emp where sal = ( select max(sal) from emp )
UNION
select * from emp where sal = ( select min(sal) from emp );

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7839 KING PRESIDENT 17-NOV-81 7500 10

PSEUDO COLUMNS :
----------------

-> Oracle pre-defined columns are called as Pseudo columns

-> Pseudo column is a column not related to one table and it is


applicable for any TABLE

-> Oracle supports different types of PSEUDO Columns

I. UID

II. USER

III. SYSDATE

IV. SYSTIMESTAMP

V. ROWID

VI. ROWNUM

VII. LEVEL

VIII. CURRVAL

IX. NEXTVAL

I. UID :
--------

-> It returns currently connected User Identification Number

II. USER :
----------

-> It returns currently connected USER Name

III. SYSDATE :
--------------

-> It returns current Server Date and Time


IV. SYSTIMESTAMP :
------------------

-> It returns current server date and time physically

ex:-

-- create a login db table with User id, UserName, Login time, Logout
time

table creation :
----------------

Create table login_details( user_id varchar2(10),


user_name varchar2(20),
login_time date,
logout_time timestamp
);

Inserting data :
----------------

SQL> Insert Into login_details values ( Uid, User, sysdate, systimestamp


);

1 row created.

SQL> select * from login_details;

USER_ID USER_NAME LOGIN_TIME LOGOUT_TIME


---------- -------------------- --------- -------------
48 ORA8PM 09-SEP-23 09-SEP-23
08.18.30.576000 PM

V. ROWID :
-----------

-> It is an Unique Value

-> RowIds are generated at time of Inserting data into Table

-> Rowid contains 16 bit Hexa decimal Character Set

-> It contains, Block Id, File Id & Record Id

-> Rowid returns Position of Record

ex:-

SQL> Select Rowid, Emp.* from emp;

ROWID EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
------------------ ------ ---------- --------- ------ --------- ------ --
---- ------
AAAE64AABAAALDRAAA 7369 SMITH CLERK 7902 17-DEC-80 1200
20
AAAE64AABAAALDRAAB 7499 ALLEN SALESMAN 7698 20-FEB-81 2400
300 30
AAAE64AABAAALDRAAC 7521 WARD SALESMAN 7698 22-FEB-81 1875
500 30
AAAE64AABAAALDRAAD 7566 JONES MANAGER 7839 02-APR-81 4462.5
20
AAAE64AABAAALDRAAE 7654 MARTIN SALESMAN 7698 28-SEP-81 1875
1400 30
AAAE64AABAAALDRAAF 7698 BLAKE MANAGER 7839 01-MAY-81 4275
30
AAAE64AABAAALDRAAG 7782 CLARK MANAGER 7839 09-JUN-81 3675
10
AAAE64AABAAALDRAAH 7788 SCOTT ANALYST 7566 15-AUG-23 4500
20
AAAE64AABAAALDRAAI 7839 KING PRESIDENT 17-NOV-81 7500
10
AAAE64AABAAALDRAAJ 7844 TURNER SALESMAN 7698 08-SEP-81 2250
0 30
AAAE64AABAAALDRAAK 7876 ADAMS CLERK 7788 12-JAN-83 1650
20
AAAE64AABAAALDRAAL 7900 JAMES CLERK 7698 03-DEC-81 1425
30
AAAE64AABAAALDRAAM 7902 FORD ANALYST 7566 21-AUG-23 4500
20
AAAE64AABAAALDRAAN 7934 MILLER CLERK 7782 23-JAN-82 1950
10

14 rows selected.

SQL> select rowid, deptno, dname, loc from dept;

ROWID DEPTNO DNAME LOC


------------------ ------ -------------- -------------
AAAE65AABAAALDZAAA 10 ACCOUNTING NEW YORK
AAAE65AABAAALDZAAB 20 RESEARCH DALLAS
AAAE65AABAAALDZAAC 30 SALES CHICAGO
AAAE65AABAAALDZAAD 40 OPERATIONS BOSTON

Other Examples :
----------------

-- waq to display first record from the table

SQL> select * from emp where rowid = (select min(rowid) from emp);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20

-- waq to display last record from the table

SQL> select * from emp where rowid = (select max(rowid) from emp);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7934 MILLER CLERK 7782 23-JAN-82 1950 10
-- Waq to Delete Duplicate Records from table Table

Emp_db:
-------
Eid ename
--- -----
101 king
102 scott
101 king
103 jones
104 smith
103 jones

Table creation :
-----------------

Create table emp_db( eid number(10), ename varchar(20) );

Insert into emp_db values ( 101, 'king' );


Insert into emp_db values ( 102, 'scott' );
Insert into emp_db values ( 101, 'king' );
Insert into emp_db values ( 103, 'jones' );
Insert into emp_db values ( 104, 'smith' );
Insert into emp_db values ( 103, 'jones' );
commit;

SQL> select rowid, eid, ename from emp_db;

ROWID EID ENAME


------------------ ------ --------------------
AAAFCDAABAAALC5AAA 101 king
AAAFCDAABAAALC5AAB 102 scott
AAAFCDAABAAALC5AAC 101 king
AAAFCDAABAAALC5AAD 103 jones
AAAFCDAABAAALC5AAE 104 smith
AAAFCDAABAAALC5AAF 103 jones

6 rows selected.

step1 :
-------

SQL> select min(rowid) from emp_db group by eid;

MIN(ROWID)
------------------
AAAFCDAABAAALC5AAB
AAAFCDAABAAALC5AAA
AAAFCDAABAAALC5AAE
AAAFCDAABAAALC5AAD

step2 :
-------

SQL> Delete from Emp_db where ROWID NOT IN ( Select min(rowid) from
emp_db group by eid );
2 rows deleted.

SQL> select *from emp_db;

EID ENAME
------ --------------------
101 king
102 scott
103 jones
104 smith

SQL> select rowid, eid, ename from emp_db;

ROWID EID ENAME


------------------ ------ --------------------
AAAFCDAABAAALC5AAA 101 king
AAAFCDAABAAALC5AAB 102 scott
AAAFCDAABAAALC5AAD 103 jones
AAAFCDAABAAALC5AAE 104 smith

-- Waq to display Duplicate records from the table

-- Waq to display Duplicate records from the table

SQL> Select * from Emp_db where ROWID NOT IN ( Select min(rowid) from
emp_db group by eid );

EID ENAME
------ --------------------
103 jones
101 king

VI. ROWNUM :
------------

-> It is an Unique Value

-> ROWNUMs are generated at the time of SELECTING data from DB TABLE

-> It is a Dynamic Value

-> Rownums are not stored in db permanently

-> Rownum returns position of record

-> After Selected data from DB TABLE rownums are generated

-> On ROWNUM pseudo column >, >=, =, between, not between operators
are not supported

ex:-

SQL> select rownum, empno, ename, sal, deptno from emp;

ROWNUM EMPNO ENAME SAL DEPTNO


------ ------ ---------- ------ ------
1 7369 SMITH 1200 20
2 7499 ALLEN 2400 30
3 7521 WARD 1875 30
4 7566 JONES 4462.5 20
5 7654 MARTIN 1875 30
6 7698 BLAKE 4275 30
7 7782 CLARK 3675 10
8 7788 SCOTT 4500 20
9 7839 KING 7500 10
10 7844 TURNER 2250 30
11 7876 ADAMS 1650 20
12 7900 JAMES 1425 30
13 7902 FORD 4500 20
14 7934 MILLER 1950 10

14 rows selected.

SQL> select rownum, empno, ename, sal, deptno from emp where deptno=20;

ROWNUM EMPNO ENAME SAL DEPTNO


------ ------ ---------- ------ ------
1 7369 SMITH 1200 20
2 7566 JONES 4462.5 20
3 7788 SCOTT 4500 20
4 7876 ADAMS 1650 20
5 7902 FORD 4500 20

SQL> select rownum, deptno, dname, loc from dept;

ROWNUM DEPTNO DNAME LOC


------ ------ -------------- -------------
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON

other examples :
----------------

-- waq to display first two records from the table

SQL> select rownum, emp.* from emp where rownum <=2;

ROWNUM EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ------ ---------- --------- ------ --------- ------ ------ ------
1 7369 SMITH CLERK 7902 17-DEC-80 1200 20
2 7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30

-- waq to display last two records from the table

SQL> select rownum, emp.* from emp where rownum <=14;

ROWNUM EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ------ ---------- --------- ------ --------- ------ ------ ------
1 7369 SMITH CLERK 7902 17-DEC-80 1200 20
2 7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
3 7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
4 7566 JONES MANAGER 7839 02-APR-81 4462.5 20
5 7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
6 7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7 7782 CLARK MANAGER 7839 09-JUN-81 3675 10
8 7788 SCOTT ANALYST 7566 15-AUG-23 4500 20
9 7839 KING PRESIDENT 17-NOV-81 7500 10
10 7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
11 7876 ADAMS CLERK 7788 12-JAN-83 1650 20
12 7900 JAMES CLERK 7698 03-DEC-81 1425 30
13 7902 FORD ANALYST 7566 21-AUG-23 4500 20
14 7934 MILLER CLERK 7782 23-JAN-82 1950 10

14 rows selected.

SQL> select rownum, emp.* from emp where rownum <=12;

ROWNUM EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ------ ---------- --------- ------ --------- ------ ------ ------
1 7369 SMITH CLERK 7902 17-DEC-80 1200 20
2 7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
3 7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
4 7566 JONES MANAGER 7839 02-APR-81 4462.5 20
5 7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
6 7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7 7782 CLARK MANAGER 7839 09-JUN-81 3675 10
8 7788 SCOTT ANALYST 7566 15-AUG-23 4500 20
9 7839 KING PRESIDENT 17-NOV-81 7500 10
10 7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
11 7876 ADAMS CLERK 7788 12-JAN-83 1650 20
12 7900 JAMES CLERK 7698 03-DEC-81 1425 30

12 rows selected.

last two records :


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

SQL> select rownum, emp.* from emp where rownum <=14


MINUS
select rownum, emp.* from emp where rownum <=12;

ROWNUM EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ------ ---------- --------- ------ --------- ------ ------ ------
13 7902 FORD ANALYST 7566 21-AUG-23 4500 20
14 7934 MILLER CLERK 7782 23-JAN-82 1950 10

note: above query is static query, because if table contains 14 rows then
it displays last two records. to display output
dynamically...

SQL> select rownum, Emp.* from emp where rownum<= ( select count(*) from
emp )
MINUS
select rownum, Emp.* from emp where rownum<= ( select count(*)-2
from emp );

ROWNUM EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ------ ---------- --------- ------ --------- ------ ------ ------
13 7902 FORD ANALYST 7566 21-AUG-23 4500 20
14 7934 MILLER CLERK 7782 23-JAN-82 1950 10
-- Waq to generate LAST 10 Trans. bank MINI statement of SBI1 customer

bank_trans: tno, acno, tdate, ttype, tamt


1 sbi1 7th sep d 1000
2 sbi1 8th sep w 500
3 sbi2 8th sep d 200
.
.

Select rownum, bank_trans.* from bank_trans where acno='SBI1' AND ROWNUM


<=( select count(*) from bank_trans where acno='SBI1' )
MINUS
Select rownum, bank_trans.* from bank_trans where acno='SBI1' AND ROWNUM
<=( select count(*)-10 from bank_trans where acno='SBI1' );

-- waq to display middle record from the table

SQL> select rownum, emp.* from emp where rownum<=( select count(*)/2 from
emp )
minus
select rownum, emp.* from emp where rownum<=( select (count(*)/2) -1
from emp );

ROWNUM EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ------ ---------- --------- ------ --------- ------ ------ ------
7 7782 CLARK MANAGER 7839 09-JUN-81 3675 10

-- waq to display Top-5 Maximum Salaries

SQL> Select rownum, Sal from ( select rownum ,sal from emp order by sal
desc ) ;

ROWNUM SAL
------ ------
1 7500
2 4500
3 4500
4 4462.5
5 4275
6 3675
7 2400
8 2250
9 1950
10 1875
11 1875
12 1650
13 1425
14 1200

14 rows selected.

SQL> Select rownum, Sal from ( select rownum ,sal from emp order by sal
desc )
where rownum <=5;

ROWNUM SAL
------ ------
1 7500
2 4500
3 4500
4 4462.5
5 4275

SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
where rownum <=5;

ROWNUM SAL
------ ------
1 7500
2 4500
3 4462.5
4 4275
5 3675

Note: To Place sub-query in FROM clause that type of queries are called
as IN-LINE SUB-QUERIES / IN-LINE VIEWS

-- waq to display Nth Maximum Salary

-- waq to display Top-5 Maximum Salaries

SQL> Select rownum, Sal from ( select rownum ,sal from emp order by sal
desc ) ;

ROWNUM SAL
------ ------
1 7500
2 4500
3 4500
4 4462.5
5 4275
6 3675
7 2400
8 2250
9 1950
10 1875
11 1875
12 1650
13 1425
14 1200

14 rows selected.

SQL> Select rownum, Sal from ( select rownum ,sal from emp order by sal
desc )
where rownum <=5;

ROWNUM SAL
------ ------
1 7500
2 4500
3 4500
4 4462.5
5 4275
SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
where rownum <=5;

ROWNUM SAL
------ ------
1 7500
2 4500
3 4462.5
4 4275
5 3675

Note: To Place sub-query in FROM clause that type of queries are called
as IN-LINE SUB-QUERIES / IN-LINE VIEWS

-- waq to display Nth Maximum Salary

SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
where rownum=3;

no rows selected

SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
2 group by rownum, sal having rownum=2;

ROWNUM SAL
------ ------
2 4500

SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
group by rownum, sal having rownum=5;

ROWNUM SAL
------ ------
5 3675

SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
group by rownum, sal having rownum=10;

ROWNUM SAL
------ ------
10 1650

SQL> Select rownum, Sal from ( select sal from emp group by sal order by
sal desc )
group by rownum, sal having rownum=&N;
Enter value for n: 1

ROWNUM SAL
------ ------
1 7500

SQL> /
Enter value for n: 4

ROWNUM SAL
------ ------
4 4275

-- waq to display following format output

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

SQL> select rpad('*',rownum,'*') from emp where rownum<=5;

RPAD('*',ROWNUM,'*')
-------------------------------------------------------------------------
---------------------------
*
**
***
****
*****

SQL> select rpad('*',rownum,'#') from emp where rownum<=5;

RPAD('*',ROWNUM,'#')
-------------------------------------------------------------------------
---------------------------
*
*#
*##
*###
*####

VII. LEVEL :
------------

-> It will arrange SELECT statement output with Inverted Tree format

-> It returns a Number

-> Level pseudo column is depends upon Hierarchical Queries

Hierarchical Queries :
**********************

-> These are queries that are executed upon the table that contains
Hierarchical Data

-> If any table contains SELF RELATION / SELF FOREIGN KEY that type of
table contains Hierarchical Data

-> To write Hierarchical queries, we need the following

i. Start With :
---------------

-> It is used to Identify Start Node of the Hierarchy


-> If start with is ommited then Oracle used all rows in the table as
ROOT Rows

ii. CONNECT BY PRIOR <cond.>:


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

-> It is used to establish relationship between Parent Node and Child


Node of the Hierarchy

-> After connect by clause to use a condition, that condition should


be contain Comparision Operator

iii. WHERE clause :


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

-> Used to filter the data without affecting other rows of the
Hierarchy

Example :
---------

EMP_DB EMP_DB
------ ------
EMPNO ENAME MGR EMPNO ENAME MGR
7369 SMITH 7902 7369 SMITH 7902
7521 JAMES 7698 7521 JAMES 7698
7566 JONES 7839 7566 JONES 7839
7698 BLAKE 7839 7698 BLAKE 7839
7839 KING 7839 KING
7788 SCOTT 7566 7788 SCOTT 7566
7902 FORD 7566 7902 FORD 7566

-- WAQ to display KING's employee Hierarchy

Select Ename from Emp_DB Start with Ename='KING'


Connect by Prior EMPNO=MGR;
7902=

KING(7839)

JONES(7566) BLAKE(7698)

SCOTT(7788) FORD(7902) JAMES(7521)

SMITH(7369)

o/p:
KING
JONES
SCOTT
FORD
SMITH
BLAKE
JAMES

SQL> SELECT ENAME FROM EMP START WITH ENAME='KING'


CONNECT BY PRIOR EMPNO=MGR;

ENAME
----------
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER

14 rows selected.

** To display output with Hierarchical Structure

SYS_CONNECT_BY_PATH :
---------------------

-> It is one of the Pre-defined Procedure

-> It displays output with Hierarchical format

SQL> SELECT SYS_CONNECT_BY_PATH( ENAME, '\') AS ORG_CHART FROM EMP


START WITH ENAME='KING'
CONNECT BY PRIOR EMPNO=MGR;

ORG_CHART
-------------------------------------------------------------------------
--------------------
\KING
\KING\JONES
\KING\JONES\SCOTT
\KING\JONES\SCOTT\ADAMS
\KING\JONES\FORD
\KING\JONES\FORD\SMITH
\KING\BLAKE
\KING\BLAKE\ALLEN
\KING\BLAKE\WARD
\KING\BLAKE\MARTIN
\KING\BLAKE\TURNER
\KING\BLAKE\JAMES
\KING\CLARK
\KING\CLARK\MILLER

14 rows selected.

SQL> SELECT LEVEL, ENAME FROM EMP


START WITH ENAME='KING'
CONNECT BY PRIOR EMPNO=MGR;

LEVEL ENAME
------ ----------
1 KING
2 JONES
3 SCOTT
4 ADAMS
3 FORD
4 SMITH
2 BLAKE
3 ALLEN
3 WARD
3 MARTIN
3 TURNER
3 JAMES
2 CLARK
3 MILLER

14 rows selected.

SQL> SELECT LEVEL, ENAME FROM EMP START WITH ENAME='KING';


SELECT LEVEL, ENAME FROM EMP START WITH ENAME='KING'
*
ERROR at line 1:
ORA-01788: CONNECT BY clause required in this query block

-- WAQ TO DISPLAY FOLLOWING FORMAT OUTPUT

KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
.
.
.
CLARK
MILLER

hint : to use LPAD function

VIII. CURRVAL :
IX. NEXTVAL :
---------------

-> These two pseudo columns are supported in SEQUENCES object

What is a Sequence ?

-> In Databases, Sequences are used to generate Sequence of Numbers


automatically

-> Sequences are supports only NUMARIC values


-> Sequences are supports two pseudo columns

i. currval :- it returns current sequence value

ii. nextval :- it returns comming generated sequence value

-> All created sequence Names are stored in USER_SEQUENCES ( system


table )

syn:-

Create Sequence <sequence_name>


Start with <value>
[Minvalue <value>]
Increment By <value>
[Mavalue <value>]
[Cache/NoCache]
[Cycle/NoCycle];

note:-

-> by default Minvalue is 1

-> Maxvalue is Un-limited

-> by default NOCACHE & NOCYCLE

-> Minvalue cache buffer size is 2kb

ex:-

Create Sequence eno_seq


start with 1
Minvalue 1
Increment By 1
Maxvalue 5
NoCache
Nocycle;

emp_db
-------
eno ( eno_seq )
1
2
3
.
.
5

SQL> Create Sequence eno_seq


start with 1
Minvalue 1
Increment By 1
Maxvalue 5
NoCache
Nocycle;
Sequence created.

SQL> drop table emp_db;

Table dropped.

SQL> create table emp_db( eno number(10), ename varchar(20) );

Table created.

SQL> Insert Into emp_db values( eno_seq.nextval, 'king' );

1 row created.

SQL> Insert Into emp_db values( eno_seq.nextval, 'scott' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ --------------------
1 king
2 scott

SQL> Insert Into emp_db values( eno_seq.nextval, 'smith' );

1 row created.

SQL> Insert Into emp_db values( eno_seq.nextval, 'allen' );

1 row created.

SQL> Insert Into emp_db values( eno_seq.nextval, 'ward' );

1 row created.

SQL> Insert Into emp_db values( eno_seq.nextval, 'jones' );


Insert Into emp_db values( eno_seq.nextval, 'jones' )
*
ERROR at line 1:
ORA-08004: sequence ENO_SEQ.NEXTVAL exceeds MAXVALUE and cannot be
instantiated

SQL> select * from emp_db;

ENO ENAME
------ --------------------
1 king
2 scott
3 smith
4 allen
5 ward

** to increment sequence MAXVALUE then

SQL> Alter Sequence eno_seq maxvalue 10;


Sequence altered.

SQL> Insert Into emp_db values( eno_seq.nextval, 'jones' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ --------------------
1 king
2 scott
3 smith
4 allen
5 ward
6 jones

6 rows selected.

** How to generate Bank account numbers in the following format ?

ex:- sbi1, sbi2,....

table creation :
----------------

Create table bank_mas( acno varchar(10), cname varchar(20));

sequence :
----------

create sequence acno_seq


start with 1
increment by 1;

SQL> Insert into bank_mas values( 'sbi'||acno_seq.nextval, 'Ramesh');

1 row created.

SQL> Insert into bank_mas values( 'sbi'||acno_seq.nextval, 'Anvesh');

1 row created.

SQL> select * from bank_mas;

ACNO CNAME
---------- --------------------
sbi1 Ramesh
sbi2 Anvesh

** to see the status of the sequence

SQL> select eno_seq.currval from dual;

CURRVAL
-------
6
SQL> SELECT SEQUENCE_NAME FROM USER_SEQUENCES;

SEQUENCE_NAME
------------------------------
ACNO_SEQ
ENO_SEQ

** Dropping Sequences

Drop Sequence eno_seq;

IV. DCL (Data Control Language ) :


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

-> DCL commands are used to control data in between users

-> There are two types of DCL commands

i. grant

ii. revoke

Grant :
-------

-> This command used to grant the permissions / privilies on db objects


to different users

syn:- Grant <priviliges>/<permission> ON <db_object> To <user1>,


<user2>,....;

ii. REVOKE :
-----------

-> Used to getback the granted permissions / priviliges

syn:- Revoke <priviliges>/<permission> ON <db_object> FROM


<user1>, <user2>,....;

** To execute above command we must contains two users

-- create a new user

-> to create a new user first connect to DBA

Username: SYSTEM
Password: server

SQL> Create user client identified by client;

sql> Grant connect, resource to client;

example :
---------

client : select * from emp_db;

-- error, table or view doesn't exists


ora8pm: grant select on emp_db to client;

cleint : select * from ora8pm.emp_db;

client : update ora8pm.emp_db set sal = 1000 where empid = 101;

note: error, In-sufficeint priviliges

ora8pm: grant update on emp_db to client;

client: update ora8pm.emp_db set sal = sal + 100 where empno=101;

-- executed

ora8pm: Grant all on emp_db to client;

note: now client got all permission on EMP_DB table

IV. DCL (Data Control Language ) :


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

-> DCL commands are used to control data in between users

-> There are two types of DCL commands

i. grant

ii. revoke

Grant :
-------

-> This command used to grant the permissions / privilies on db objects


to different users

syn:- Grant <priviliges>/<permission> ON <db_object> To <user1>,


<user2>,....;

ii. REVOKE :
-----------

-> Used to getback the granted permissions / priviliges

syn:- Revoke <priviliges>/<permission> ON <db_object> FROM


<user1>, <user2>,....;

** To execute above command we must contains two users

-- create a new user

-> to create a new user first connect to DBA

Username: SYSTEM
Password: server

SQL> Create user client identified by client;


sql> Grant connect, resource to client;

example :
---------

client : select * from emp_db;

-- error, table or view doesn't exists

ora8pm: grant select on emp_db to client;

cleint : select * from ora8pm.emp_db;

client : update ora8pm.emp_db set sal = 1000 where empid = 101;

note: error, In-sufficeint priviliges

ora8pm: grant update on emp_db to client;

client: update ora8pm.emp_db set sal = sal + 100 where empno=101;

-- executed

ora8pm: Grant all on emp_db to client;

note: now client got all permissions on EMP_DB table

REVOKE :
--------

ora8pm : Revoke SELECT on emp_db from Client;

client: select * from ora8pm.emp_db;

-- error message, in-sufficient priviliges

ora8pm : Revoke ALL on emp_db from CLIENT;

** to see the granted permissions

select * from user_tab_privs_made; -- to execute inside ORA8PM


user

** to see the received permissions

select * from user_tab_privs_recd; -- to execute inside CLIENT


user

V. TCL ( Transaction Control Language ) :


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

-> By using this language commands, we can control DML transactions

-> There are three types of TCL commands

i. Commit
ii. Savepoint

iii. Rollback

i. commit :
-----------

-> Used to save DML trasactions into db permanently

-> There are two types of COMMITs

a. Implicit Commit : It is performed by Oracle automatically

ex: DDL Commands

b. Explicit Commit : It is performed by User explicitely

ex: DML commands

ii. SAVEPOINT :
---------------

-> used to create a book mark

syn:- SAVEPOINT <savepoint_name>;

iii. ROLLBACK :
---------------

-> Used to undo DML transactions

-> after COMMIT whatever DML transactions are executed all are undo

example:
--------

sql> select * from emp;

-- 14 rows selected

sql> delete from emp where empno=7788;

sql> savepoint s1;

sql> Insert Into emp values( 1001, 'raj', 'clerk', 7839, sysdate, 3000,
100, 10 );

sql> savepoint s2;

sql> Update emp set sal = sal + 1000;

sql> select * from emp;

-- 14 rows selected

sql> Rollback to s2; -- here UPDATE tran. is undo


sql> commit; -- once commit is executed whatever SAVEPOINTS are
there all are destroyed first, after that
inside savepoints Whatever transactions are there
all are committed;

SQL> rollback to s1;


rollback to s1
*
ERROR at line 1:
ORA-01086: savepoint 'S1' never established in this session or is invalid

db objects :
------------

-> A component automatically registered in system software is called


as db objects

ex: TABLES, VIEWS, INDEXES, SEQUENCES, SYNONYMS, ROLES,


ETC.,

VIEWS :
-------

-> View is one of the Virtual DB object

-> Views are created based on BASE TABLE or EXISTING table

-> views are created by using SELECT statement output

-> Views doesn't hold any data and it re-presents only STRUCTURE

-> Views holds results of query

-> Views supports DML, SELECT & DESC commands

-> To perform any DML transactions on views that are reflected on


BASETABLE and vice versa.

-> All created views are stored in USER_VIEWS ( SYSTEM TABLE )

Adv. :
------

-> Views provides security on DB OBJECTS

-> by using views to hold Multiple tables information( updated


information ) into a Single Table

syn:- Create or replace view <view_name>


As
<select statement>;

ex:-

SQL> Create or replace view V1


as
select * from emp;
Create or replace view V1
*
ERROR at line 1:
ORA-01031: insufficient privileges

** first take permission from DBA user

connect to DBA :
----------------

username: system
password: server

SQL> grant create view to ora8pm;

Grant succeeded.

ORA8PM :
--------

SQL> Create or replace view V1


as
select * from emp;

View created.

SQL> SELECT * FROM V1;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10
1001 raj clerk 7839 14-SEP-23 3000 100 10

14 rows selected.

db objects :
------------

-> A component automatically registered in system software is called


as db objects

ex: TABLES, VIEWS, INDEXES, SEQUENCES, SYNONYMS, ROLES,


ETC.,

VIEWS :
-------
-> View is one of the Virtual DB object

-> Views are created based on BASE TABLE or EXISTING table

-> views are created by using SELECT statement output

-> Views doesn't hold any data and it re-presents only STRUCTURE

-> Views holds results of query

-> Views supports DML, SELECT & DESC commands

-> To perform any DML transactions on views that are reflected on


BASETABLE and vice versa.

-> All created views are stored in USER_VIEWS ( SYSTEM TABLE )

Adv. :
------

-> Views provides security on DB OBJECTS

-> by using views to hold Multiple tables information( updated


information ) into a Single Table

syn:- Create or replace view <view_name>


As
<select statement>;

ex:-

SQL> Create or replace view V1


as
select * from emp;
Create or replace view V1
*
ERROR at line 1:
ORA-01031: insufficient privileges

** first take permission from DBA user

connect to DBA :
----------------

username: system
password: server

SQL> grant create view to ora8pm;

Grant succeeded.

ORA8PM :
--------

SQL> Create or replace view V1


as
select * from emp;
View created.

SQL> SELECT * FROM V1;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10
1001 raj clerk 7839 14-SEP-23 3000 100 10

14 rows selected.

Inserting data into V1 view :


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

SQL> Insert into v1 values( 1002, 'Ramesh', 'manager', 7839, sysdate,


4000,0, 20 );

1 row created.

SQL> select * from v1;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 1200
20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400
300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875
500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5
20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875
1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275
30
7782 CLARK MANAGER 7839 09-JUN-81 3675
10
7839 KING PRESIDENT 17-NOV-81 7500
10
7844 TURNER SALESMAN 7698 08-SEP-81 2250
0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650
20
7900 JAMES CLERK 7698 03-DEC-81 1425
30
7902 FORD ANALYST 7566 21-AUG-23 4500
20
7934 MILLER CLERK 7782 23-JAN-82 1950
10
1001 raj clerk 7839 14-SEP-23 3000
100 10
1002 Ramesh manager 7839 15-SEP-23 4000
0 20

15 rows selected.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 1200
20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400
300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875
500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5
20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875
1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275
30
7782 CLARK MANAGER 7839 09-JUN-81 3675
10
7839 KING PRESIDENT 17-NOV-81 7500
10
7844 TURNER SALESMAN 7698 08-SEP-81 2250
0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650
20
7900 JAMES CLERK 7698 03-DEC-81 1425
30
7902 FORD ANALYST 7566 21-AUG-23 4500
20
7934 MILLER CLERK 7782 23-JAN-82 1950
10
1001 raj clerk 7839 14-SEP-23 3000
100 10
1002 Ramesh manager 7839 15-SEP-23 4000
0 20

15 rows selected.

ex2:-

Create or replace view DEPT10


as
select empno, ename, sal, deptno from emp where deptno=10;

View created.

SQL> select * from dept10;


EMPNO ENAME SAL DEPTNO
---------- ---------- ---------- ----------
7782 CLARK 3675 10
7839 KING 7500 10
7934 MILLER 1950 10
1001 raj 3000 10

View constraints :
------------------=

WITH CHECK OPTION :


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

-> If inserting data satisfies view condition then record inserting


into VIEW & BASE TABLE otherwise it returns error message

ex:-

SQL> Create or replace view dept10


as
select empno, ename, sal, deptno from emp where deptno=10 with
check option;

View created.

SQL> insert into dept10 values( 1003, 'kris', 5000, 20 );


insert into dept10 values( 1003, 'kris', 5000, 20 )
*
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation

SQL> insert into dept10 values( 1003, 'kris', 5000, 10 );

1 row created.

SQL> select * from dept10;

EMPNO ENAME SAL DEPTNO


---------- ---------- ---------- ----------
7782 CLARK 3675 10
7839 KING 7500 10
7934 MILLER 1950 10
1001 raj 3000 10

ii. READ ONLY VIEWS :


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

-> these views are only for READING purpose

-> On Read only views we can not perform DML commands

-> only SELECCT & DESC commands are valid

ex:-

SQL> Create or replace view READ_VIEW


As
Select * from emp with read only;
View created.

SQL> select * from read_view;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 1200
20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400
300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875
500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5
20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875
1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275
30
7782 CLARK MANAGER 7839 09-JUN-81 3675
10
7839 KING PRESIDENT 17-NOV-81 7500
10
7844 TURNER SALESMAN 7698 08-SEP-81 2250
0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650
20
7900 JAMES CLERK 7698 03-DEC-81 1425
30
7902 FORD ANALYST 7566 21-AUG-23 4500
20
7934 MILLER CLERK 7782 23-JAN-82 1950
10
1001 raj clerk 7839 14-SEP-23 3000
100 10
1002 Ramesh manager 7839 15-SEP-23 4000
0 20
1003 kris 5000
10

16 rows selected.

SQL> delete from read_view;


delete from read_view
*
ERROR at line 1:
ORA-42399: cannot perform a DML operation on a read-only view

II. COMPLEX VIEWS :


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

-> These views are created by SELECT statement contains Join


Conditions/Arithmetic Operations/Group by clause / Having clause,
etc.,

-> On complex views DML commands Partially supported

-> Only SELECT & DESC commands are valid


ex:-

SQL> Create or replace view EMPDEPT


As
select empno, ename, job, sal, dept.deptno, dname, loc from emp,
dept
where emp.deptno =
dept.deptno;

View created.

SQL> select * from empdept;

EMPNO ENAME JOB SAL DEPTNO DNAME LOC


---------- ---------- --------- ---------- ---------- -------------- ----
---------
7369 SMITH CLERK 1200 20 RESEARCH
DALLAS
7499 ALLEN SALESMAN 2400 30 SALES
CHICAGO
7521 WARD SALESMAN 1875 30 SALES
CHICAGO
7566 JONES MANAGER 4462.5 20 RESEARCH
DALLAS
7654 MARTIN SALESMAN 1875 30 SALES
CHICAGO
7698 BLAKE MANAGER 4275 30 SALES
CHICAGO
7782 CLARK MANAGER 3675 10 ACCOUNTING NEW
YORK
7839 KING PRESIDENT 7500 10 ACCOUNTING NEW
YORK
7844 TURNER SALESMAN 2250 30 SALES
CHICAGO
7876 ADAMS CLERK 1650 20 RESEARCH
DALLAS
7900 JAMES CLERK 1425 30 SALES
CHICAGO
7902 FORD ANALYST 4500 20 RESEARCH
DALLAS
7934 MILLER CLERK 1950 10 ACCOUNTING NEW
YORK
1001 raj clerk 3000 10 ACCOUNTING NEW
YORK
1002 Ramesh manager 4000 20 RESEARCH
DALLAS
1003 kris 5000 10 ACCOUNTING NEW
YORK

16 rows selected.

SQL> select * from empdept;

EMPNO ENAME JOB SAL DEPTNO DNAME LOC


---------- ---------- --------- ---------- ---------- -------------- ----
---------
7369 SMITH CLERK 1200 20 RESEARCH
DALLAS
7499 ALLEN SALESMAN 2400 30 SALES
CHICAGO
7521 WARD SALESMAN 1875 30 SALES
CHICAGO
7566 JONES MANAGER 4462.5 20 RESEARCH
DALLAS
7654 MARTIN SALESMAN 1875 30 SALES
CHICAGO
7698 BLAKE MANAGER 4275 30 SALES
CHICAGO
7782 CLARK MANAGER 3675 10 ACCOUNTING NEW
YORK
7839 KING PRESIDENT 7500 10 ACCOUNTING NEW
YORK
7844 TURNER SALESMAN 2250 30 SALES
CHICAGO
7876 ADAMS CLERK 1650 20 RESEARCH
DALLAS
7900 JAMES CLERK 1425 30 SALES
CHICAGO
7902 FORD ANALYST 4500 20 RESEARCH
DALLAS
7934 MILLER CLERK 1950 10 ACCOUNTING NEW
YORK
1001 raj clerk 3000 10 ACCOUNTING NEW
YORK
1002 Ramesh manager 4000 20 RESEARCH
DALLAS
1003 kris 5000 10 ACCOUNTING NEW
YORK

16 rows selected.

Insert command on COMPLEX View :


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

SQL> Insert Into empdept values ( 1004, 'aaa', 'clerk', 1500, 10,
'ACCOUNTING', 'NEW YORK');
Insert Into empdept values ( 1004, 'aaa', 'clerk', 1500, 10,
'ACCOUNTING', 'NEW YORK')
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table

** Views doesn't hold any data represents only Structure. here we can
justify with one example :
*************************************************************************
************************

SQL> select rowid, empno, ename, sal, deptno from emp;

ROWID EMPNO ENAME SAL DEPTNO


------------------ ---------- ---------- ---------- ----------
AAAE64AABAAALDRAAA 7369 SMITH 1200 20
AAAE64AABAAALDRAAB 7499 ALLEN 2400 30
AAAE64AABAAALDRAAC 7521 WARD 1875 30
AAAE64AABAAALDRAAD 7566 JONES 4462.5 20
AAAE64AABAAALDRAAE 7654 MARTIN 1875 30
AAAE64AABAAALDRAAF 7698 BLAKE 4275 30
AAAE64AABAAALDRAAG 7782 CLARK 3675 10
AAAE64AABAAALDRAAI 7839 KING 7500 10
AAAE64AABAAALDRAAJ 7844 TURNER 2250 30
AAAE64AABAAALDRAAK 7876 ADAMS 1650 20
AAAE64AABAAALDRAAL 7900 JAMES 1425 30
AAAE64AABAAALDRAAM 7902 FORD 4500 20
AAAE64AABAAALDRAAN 7934 MILLER 1950 10
AAAE64AABAAALDRAAO 1001 raj 3000 10
AAAE64AABAAALDRAAP 1002 Ramesh 4000 20
AAAE64AABAAALDRAAQ 1003 kris 5000 10

16 rows selected.

SQL> select rowid, empno, ename, sal, deptno from v1;

ROWID EMPNO ENAME SAL DEPTNO


------------------ ---------- ---------- ---------- ----------
AAAE64AABAAALDRAAA 7369 SMITH 1200 20
AAAE64AABAAALDRAAB 7499 ALLEN 2400 30
AAAE64AABAAALDRAAC 7521 WARD 1875 30
AAAE64AABAAALDRAAD 7566 JONES 4462.5 20
AAAE64AABAAALDRAAE 7654 MARTIN 1875 30
AAAE64AABAAALDRAAF 7698 BLAKE 4275 30
AAAE64AABAAALDRAAG 7782 CLARK 3675 10
AAAE64AABAAALDRAAI 7839 KING 7500 10
AAAE64AABAAALDRAAJ 7844 TURNER 2250 30
AAAE64AABAAALDRAAK 7876 ADAMS 1650 20
AAAE64AABAAALDRAAL 7900 JAMES 1425 30
AAAE64AABAAALDRAAM 7902 FORD 4500 20
AAAE64AABAAALDRAAN 7934 MILLER 1950 10
AAAE64AABAAALDRAAO 1001 raj 3000 10
AAAE64AABAAALDRAAP 1002 Ramesh 4000 20
AAAE64AABAAALDRAAQ 1003 kris 5000 10

16 rows selected.

note: Here EMP & V1 both contains same ROWIDs

III. MATERIALIAZED VIEW :


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

-> To store the data in views is called as Materialized views

** to see the created views list

SQL> select view_name from user_views;

VIEW_NAME
------------------------------
DEPT10
EMPDEPT
READ_VIEW
V1

** dropping views :
-------------------

-- Drop view view_name


ex:- Drop view v1;

-> Once drop the view ( v1 ) is there base table available ?

Yes, Base table is available

-> But, Once drop the BASETABLE(emp) is there Dependent views are
available or not ?

Yes Views are available, but those views doesn't contain any
structure

INDEXES :
---------

-> Indexes are used to Improves the performance while retrieving or


manipulating data

-> Indexes are activated whenever INDEXED column is placed in WHERE


clause of SELECT statement

-> Indexes are also actived when the tables are manipulated by Other
Users or By other application s/w tools.

emp -> empno(index)

select * from emp where deptno=10;

INDEXES :
---------

-> Indexes are used to Improves the performance while retrieving or


manipulating data

-> Indexes are activated whenever INDEXED column is placed in WHERE


clause of SELECT statement

-> Indexes are also actived when the tables are manipulated by Other
Users or By other application s/w tools.

-> All Created indexes are stored in USER_INDEXES ( pre-defined table )

TYPES OF INDEXES :
******************

-> Oracle supports two types of indexes

I. IMPLICIT INDEXES

II. EXPLICIT INDEXES

I. IMPLICIT INDEXES :
---------------------
-> These indexes are created by Oracle automatically

ex:- Primary Key, Unique constraints

II. EXPLICIT INDEXES :


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

-> These indexes are created by user explicitely

-> Explicit Indexes are classified into different types

syn:-

Create Index <Index_name> ON <db_object> ( col1, col2,... );

i. Normal Indexes :
-------------------

-> These indexes are created on any db column inside the table

ex:-

SQL> Create Index Empno_Ind On Emp(Empno);

Index created.

SQL> select * from emp where empno=7934;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7934 MILLER CLERK 7782 23-JAN-82 1950 10

ii. Functional Based Indexes :


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

-> These Indexes are created by using BUILT-IN Functions

ex:-

job -> 1000 records

-- 600 records are small letters

-- 400 records are capital letters

select * from emp where job='CLERK'; -- here internally oracle


checking 1000 records

ex:-

SQL> Create Index job_fun_ind on emp( upper(job) );

SQL> select * from emp where job='CLERK'; -- here internally oracle


checking 400 records only
iii. Composite Indexes :
------------------------

-> To create index on morethan one column is called as Composite


Indexes

-> In composite Indexes data is checking pairwise

ex:-

SQL> Create Index deptno_job_comp_ind on Emp(Deptno, Job );

SQL> Select * from emp where DEPTNO=10 AND JOB='MANAGER';

iv. UNIQUE Indexes :


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

-> these indexes are created on UNIQUE data columns

-> Once add Primary key or Unique constraint automatically UNIQUE INDEX
added

syn:-

Create Unique Index empno_uni_ind on Emp( Empno );

select * from emp where empno=7788;

** to see the created indexes names

SQL> select index_name from user_indexes;

INDEX_NAME
------------------------------
DEPT_MAS_DEPT_ID_PK
PROD_MAS_CID_PID_PK
EMPNO_IND

** Dropping Indexes :
---------------------

syn:- Drop Index <Index_name>;

ex:- Drop Index my_ind;

** Indexes are not created on if any db column contains un-structured


datatype( ex:- lob, blob, clob, raw, long raw, bfile, .... );

SYNONYMS :
----------

-> Synonym is a another name for a given table name

-> Synonyms are created on Entire Table

-> Synonyms supports DML, DRL & DESC commands are supported
-> Synonyms provides High Security on DB TABLES Compare to Views

-> All Created synonyms are stored in USER_SYNONYM( system table )

-> To perform any DML commands on Synonyms that are reflected on


BASETABLE and VICE VERSA

TYPES OF SYNONYMS :
-------------------

i. Private Synonym

ii. Public Synonym

i. Private Synonym :
--------------------

-> It is created by owner( user )

-> Private synonyms provides security on DB TABLE NAME only

syn:- Create synonym <synonym_name> for <table_name>;

before creating synonyms first take permission from DBA USER :


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

SQL> grant create synonym to ora8pm;

Grant succeeded.

In Ora8pm User:
---------------

SQL> Create synonym my_syn for emp;

Synonym created.

SQL> select * from my_syn;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10
1001 raj clerk 7839 14-SEP-23 3000 100 10
1002 Ramesh manager 7839 15-SEP-23 4000 0 20
1003 kris 5000 10
16 rows selected.

SQL> delete from my_syn where empno<1100;

3 rows deleted.

SQL> select * from my_syn;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

Granting Private Synonyms :


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

ora8pm: Grant select on my_syn to client;

client: select * from ora8pm.my_syn;

note : Here security provides on TABLE NAME but, not on USERNAME

ii. PUBLIC SYNONYMS :


---------------------
-> These synonyms are created on entire table

-> Public synonyms are created by DBA only

-> Only One Grant permission to create public synonym

syn:-

Create Public synonym <synonym_name> for <table_name>;

ex:-

Connect to DBA user :


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

username : system
password : server

sql> create public synonym ABC for ora8pm.emp;

sql> Grant all on ABC to public; -- here only one grant permission all
user can access ABC synonym

connect to ORA8PM USER :


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

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10
1001 raj clerk 7839 14-SEP-23 3000 100 10
1002 Ramesh manager 7839 15-SEP-23 4000 0 20
1003 kris 5000 10

16 rows selected.

SQL> select * from abc;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10
1001 raj clerk 7839 14-SEP-23 3000 100 10
1002 Ramesh manager 7839 15-SEP-23 4000 0 20
1003 kris 5000 10

16 rows selected.

NOTE : Here security provides on Table name and User Name also

Connect to another user : CLIENT :


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

SQL> select * from abc;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10
1001 raj clerk 7839 14-SEP-23 3000 100 10
1002 Ramesh manager 7839 15-SEP-23 4000 0 20
1003 kris 5000 10

16 rows selected.

** to see the created synonyms

select * from user_synonyms;

** dropping synonyms

drop synonym my_syn; -- it is dropped by owner(user)

drop public synonym my_syn; -- only dba can drop

JOINS :
-------
-> To retrieving data from morethan one table in a single query by
using JOINS

-> Join is one of main feature of Relational databases

syn of join :-
**************

Select table1.col1, table1.col2,.. table2.col1, table2.col2,... from


<table1>, <table2>,...
Where ( table1.col =
<able2.col);

-> If 'n' tables are joined, there will min. 'n-1' join conditions are
required

-> Join queries are mainly used for to generate reports like Daily
reports, weekly reports, monthly reports,
yearly reports, salary statements, invoices, etc.,

TYPES OF JOINS :
----------------

-> Oracle supports 5 types of JOINs

I. EQUI JOIN / SIMPLE JOIN

II. NON-EQUI JOIN

III. CARTESIAN JOIN

IV. OUTER JOIN

V. SELF JOIN

-> To write any types of joins, Oracle returns one common error
message is

SQL> SELECT DEPTNO FROM EMP, DEPT;


SELECT DEPTNO FROM EMP, DEPT
*
ERROR at line 1:
ORA-00918: column ambiguously defined

** To overcome this error message then to use TABLE ALAISES

TABLE ALAISE :
--------------

-> Aliase name is given to next to table name is called as Table Alaise

ex:- Employee_master_Table EMT, Employee_Transaction_Table ETT,


EMP e, Dept d, etc.,

SQL> SELECT e.DEPTNO FROM EMP e, DEPT d;

I. EQUI JOIN / SIMPLE JOIN :


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

-> To retrieving data from morethan one table in a single query by using
EQUALITY OPERATOR( = ) in Join Condition is called as
Equi Join

-> To Write Equi Join Queries, Joining tables should be contain atleast
one similar column name and corresponding columns
datatypes should be same.

example :
----------

-> write a query to display employee details and corresponding


employee dept. details

SQL> Select * From Emp, Dept Where Emp.Deptno = Dept.Deptno;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO


DNAME LOC
------ ---------- --------- ------ --------- ------ ------ ------ ------
-------------- -------------
7369 SMITH CLERK 7902 17-DEC-80 1200 20 20
RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 30
SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 30
SALES CHICAGO
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 20
RESEARCH DALLAS
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 30
SALES CHICAGO
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 30
SALES CHICAGO
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 10
ACCOUNTING NEW YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 10
ACCOUNTING NEW YORK
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 30
SALES CHICAGO
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 20
RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 1425 30 30
SALES CHICAGO
7902 FORD ANALYST 7566 21-AUG-23 4500 20 20
RESEARCH DALLAS
7934 MILLER CLERK 7782 23-JAN-82 1950 10 10
ACCOUNTING NEW YORK

13 rows selected.

-- write a query to display who are working in NEW YORK location

SQL> Select Emp.*, Loc from Emp, Dept Where Emp.Deptno = Dept.Deptno and
loc='NEW YORK';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO LOC


------ ---------- --------- ------ --------- ------ ------ ------ -------
------
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 NEW
YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 NEW
YORK
7934 MILLER CLERK 7782 23-JAN-82 1950 10 NEW
YORK

-- waq to display who joined 1981 in SALES dept.

Select Emp.*, Dname from Emp, Dept Where Emp.Deptno = Dept.deptno


And
Dname='SALES'
And
Hiredate like '%81';

-- waq to display in Research Dept. Howmany Employees are Joined

SQL> select dname, Count(*) from emp, dept where emp.deptno=dept.deptno


and dname='RESEARCH'
2 group by dname;

DNAME COUNT(*)
-------------- --------
RESEARCH 4

-- waq to display in RESEARCH howmany employees are working

-- waq to display in BOSTON howmany employees are working

-- waq to display SALES dept. Maximum Salary

-- waq to dislay ACCOUNTING dept. Min and Max Salaries

std_mas: std_id, std_name, class

std_addr: std_id, addr1, addr2, addr3, addr4, mobileno, mail id,

std_marks: std_id, maths, phys, chem

std_grades : std_id, total, avg, grade, rank,

std_report: std_id, std_name, maths, phys, chem, rank

I. EQUI JOIN / SIMPLE JOIN :


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

-> To retrieving data from morethan one table in a single query by using
EQUALITY OPERATOR( = ) in Join Condition is called as
Equi Join
-> To Write Equi Join Queries, Joining tables should be contain atleast
one similar column name and corresponding columns
datatypes should be same.

example :
----------

-> write a query to display employee details and corresponding


employee dept. details

SQL> Select * From Emp, Dept Where Emp.Deptno = Dept.Deptno;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO


DNAME LOC
------ ---------- --------- ------ --------- ------ ------ ------ ------
-------------- -------------
7369 SMITH CLERK 7902 17-DEC-80 1200 20 20
RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 30
SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 30
SALES CHICAGO
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 20
RESEARCH DALLAS
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 30
SALES CHICAGO
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 30
SALES CHICAGO
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 10
ACCOUNTING NEW YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 10
ACCOUNTING NEW YORK
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 30
SALES CHICAGO
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 20
RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 1425 30 30
SALES CHICAGO
7902 FORD ANALYST 7566 21-AUG-23 4500 20 20
RESEARCH DALLAS
7934 MILLER CLERK 7782 23-JAN-82 1950 10 10
ACCOUNTING NEW YORK

13 rows selected.

-- write a query to display who are working in NEW YORK location

SQL> Select Emp.*, Loc from Emp, Dept Where Emp.Deptno = Dept.Deptno and
loc='NEW YORK';

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO LOC


------ ---------- --------- ------ --------- ------ ------ ------ -------
------
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 NEW
YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 NEW
YORK
7934 MILLER CLERK 7782 23-JAN-82 1950 10 NEW
YORK

-- waq to display who joined 1981 in SALES dept.

Select Emp.*, Dname from Emp, Dept Where Emp.Deptno = Dept.deptno


And
Dname='SALES'
And
Hiredate like '%81';

-- waq to display in Research Dept. Howmany Employees are Joined

SQL> select dname, Count(*) from emp, dept where emp.deptno=dept.deptno


and dname='RESEARCH'
group by dname;

DNAME COUNT(*)
-------------- --------
RESEARCH 4

-- waq to display in RESEARCH howmany employees are working

SQL> select dname, Count(*) from emp, dept where emp.deptno=dept.deptno


and dname='RESEARCH'
group by dname;

DNAME COUNT(*)
-------------- --------
RESEARCH 4

-- waq to display in BOSTON howmany employees are working

SQL> Select Loc, count(*) from Emp, Dept


where Emp.Deptno = Dept.Deptno and loc='NEW
YORK'
Group by Loc;

LOC COUNT(*)
------------- --------
NEW YORK 3

-- waq to display SALES dept. Maximum Salary

SQL> SELECT DNAME, MAX(SAL) FROM EMP , DEPT WHERE EMP.DEPTNO =


DEPT.DEPTNO AND DNAME='SALES'

GROUP BY DNAME;

DNAME MAX(SAL)
-------------- --------
SALES 4275

SQL> SELECT MAX(SAL) FROM EMP , DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO AND
DNAME='SALES';

MAX(SAL)
--------
4275

-- waq to dislay ACCOUNTING dept. Min and Max Salaries

SQL> SELECT DNAME, MAX(SAL), MIN(SAL) FROM EMP , DEPT WHERE EMP.DEPTNO =
DEPT.DEPTNO
AND

DNAME='ACCOUNTING'
GROUP BY DNAME;

DNAME MAX(SAL) MIN(SAL)


-------------- -------- --------
ACCOUNTING 7500 1950

Other Examples :
----------------

Bank_mas: Acno, Cname, Addr, Acc_type, Opening Date, Bal


sbi1 king hyd s 21st_sep 4000
sbi2 allen sec c 19th_sep 9000

Bank_Trans: Tno, Acno, Tdate, Ttype, Tamt


1 sbi1 21st_sep d 1000
2 sbi2 21st_sep w 300

-- waq to display customer details and corresponding each customer trans.


details

Select * from bank_mas, bank_trans Where Bank_mas.Acno =


Bank_Trans.Acno;

-- waq to display SBI1 customer last month account statement

Select BM.acno, Cname, Acc_type, Tdate, Ttype, Tamt


from Bank_mas BM, Bank_trans BT
where Bm.Acno = Bt.Acno
And
Bm.Acno = 'sbi1'
And
to_char(tdate,'mm-yyyy') =
to_char( add_months(sysdate,-1),'mm-yyyy');

-- waq to display sbi1 customer current month till date account statement

Select Bm.Acno, Cname, Acc_type, Tdate, Ttype, Tamt


From Bank_mas BM, Bank_Trans BT
Where Bm.Acno = Bt.Acno
And
Bm.Acno = 'sbi1'
And
to_char(tdate, 'mm-yyyy' ) =
to_char( sysdate, 'mm-yyyy');

-- waq to display last month each customer howmany Deposits and Withdraws
are completed
Select Bm.Acno, Cname, TType, Count(*) from Bank_mas BM, Bank_Trans
Bt
where Bm.acno = Bt.Acno
Group by Bm.Acno, Cname,
Ttype
Order by
bm.Acno, Ttype;

-- waq to display SBI1 Customer current month till date howmany withdraws
are completed

Select Count(*) from Bank_trans


Where acno = 'sbi1'
and
Ttype='w'
and
to_char(tdate, 'mm-yyyy' ) = to_char( sysdate, 'mm-yyyy');

II. NON EQUI-JOIN :


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

-> To retrieving data from morethan one table in a single query without
using Equality Operator is called as
Non-Equi Join

-> In Non-Equi Joins, Join conditions are comparing with >, <, >=, <=,
between, not between, etc., operators

Ex:-

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

SQL> select * from Salgrade;

GRADE LOSAL HISAL


------ ------ ------
1 700 1200
2 1201 1400
3 1401 2000
4 2001 3000
5 3001 9999

-- waq to display Employee details and corresponding each employee


Grades

SQL> select Emp.*, Grade from Emp, SalGrade


Where Sal Between Losal and Hisal;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO GRADE


------ ---------- --------- ------ --------- ------ ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20 1
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 3
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 3
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 3
7900 JAMES CLERK 7698 03-DEC-81 1425 30 3
7934 MILLER CLERK 7782 23-JAN-82 1950 10 3
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 4
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 4
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 5
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 5
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 5
7839 KING PRESIDENT 17-NOV-81 7500 10 5
7902 FORD ANALYST 7566 21-AUG-23 4500 20 5

13 rows selected.

** Example of EQUI + NON-EQUI Join :


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

-- waq to display Employee Name, Dept. Dname and Corresponding Employee


Grade

SQL> Select Ename, Dname, Grade


From Emp, Dept, Salgrade
Where Emp.Deptno = dept.Deptno
And
Sal Between Losal and Hisal;

ENAME DNAME GRADE


---------- -------------- ------
SMITH RESEARCH 1
ALLEN SALES 4
WARD SALES 3
JONES RESEARCH 5
MARTIN SALES 3
BLAKE SALES 5
CLARK ACCOUNTING 5
KING ACCOUNTING 5
TURNER SALES 4
ADAMS RESEARCH 3
JAMES SALES 3
FORD RESEARCH 5
MILLER ACCOUNTING 3

13 rows selected.
III. Cartesian Join :
---------------------

-> To Retrieving data from morethan one table in a single query without
using any condition is called as Cartesian Join

-> In Cartesian Join, Output displays like No.of records in Table1 is


multiply with No.of records in Table2 i.e., if
table1 contains 8 rows & table2 contains 8 then total no.of records
64 ( 8 x 8 )

-> Cartesian Join is also called as Cross Join

ex:-

SQL> Select * from Emp, Dept;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO


DNAME LOC
------ ---------- --------- ------ --------- ------ ------ ------ ------
-------------- -------------
7369 SMITH CLERK 7902 17-DEC-80 1200 20 10
ACCOUNTING NEW YORK
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 10
ACCOUNTING NEW YORK
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 10
ACCOUNTING NEW YORK
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 10
ACCOUNTING NEW YORK
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 10
ACCOUNTING NEW YORK
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 10
ACCOUNTING NEW YORK
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 10
ACCOUNTING NEW YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 10
ACCOUNTING NEW YORK
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 10
ACCOUNTING NEW YORK
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 10
ACCOUNTING NEW YORK
7900 JAMES CLERK 7698 03-DEC-81 1425 30 10
ACCOUNTING NEW YORK
7902 FORD ANALYST 7566 21-AUG-23 4500 20 10
ACCOUNTING NEW YORK
7934 MILLER CLERK 7782 23-JAN-82 1950 10 10
ACCOUNTING NEW YORK
7369 SMITH CLERK 7902 17-DEC-80 1200 20 20
RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 20
RESEARCH DALLAS
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 20
RESEARCH DALLAS
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 20
RESEARCH DALLAS
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 20
RESEARCH DALLAS
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 20
RESEARCH DALLAS
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 20
RESEARCH DALLAS
7839 KING PRESIDENT 17-NOV-81 7500 10 20
RESEARCH DALLAS
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 20
RESEARCH DALLAS
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 20
RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 1425 30 20
RESEARCH DALLAS
7902 FORD ANALYST 7566 21-AUG-23 4500 20 20
RESEARCH DALLAS
7934 MILLER CLERK 7782 23-JAN-82 1950 10 20
RESEARCH DALLAS
7369 SMITH CLERK 7902 17-DEC-80 1200 20 30
SALES CHICAGO
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 30
SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 30
SALES CHICAGO
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 30
SALES CHICAGO
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 30
SALES CHICAGO
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 30
SALES CHICAGO
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 30
SALES CHICAGO
7839 KING PRESIDENT 17-NOV-81 7500 10 30
SALES CHICAGO
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 30
SALES CHICAGO
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 30
SALES CHICAGO
7900 JAMES CLERK 7698 03-DEC-81 1425 30 30
SALES CHICAGO
7902 FORD ANALYST 7566 21-AUG-23 4500 20 30
SALES CHICAGO
7934 MILLER CLERK 7782 23-JAN-82 1950 10 30
SALES CHICAGO
7369 SMITH CLERK 7902 17-DEC-80 1200 20 40
OPERATIONS BOSTON
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 40
OPERATIONS BOSTON
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 40
OPERATIONS BOSTON
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 40
OPERATIONS BOSTON
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 40
OPERATIONS BOSTON
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 40
OPERATIONS BOSTON
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 40
OPERATIONS BOSTON
7839 KING PRESIDENT 17-NOV-81 7500 10 40
OPERATIONS BOSTON
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 40
OPERATIONS BOSTON
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 40
OPERATIONS BOSTON
7900 JAMES CLERK 7698 03-DEC-81 1425 30 40
OPERATIONS BOSTON
7902 FORD ANALYST 7566 21-AUG-23 4500 20 40
OPERATIONS BOSTON
7934 MILLER CLERK 7782 23-JAN-82 1950 10 40
OPERATIONS BOSTON

52 rows selected.

IV. OUTER JOINS :


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

-> In this joins, first it displays matching records from Table1 ,Table2
and un-matched records from either table1, or table2 or Both Tables

-> Outer Joins are clasified into 3 types

i. Right Outer Join

ii. Left Outer Join

iii. Full Outer Join

** from Oracle 10g version onwards Outer is re-presented with (+)

i. Right Outer Join :


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

-> In this joins, first it displays matching records from table1,


table2 and un-matched records from right side of the table on
Join Condition.

ex:-

-- waq to display employee details with dept.with and in-which dept. no


employees are working

SQL> Select * from Emp, Dept where Emp.Deptno (+)=Dept.Deptno;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO


DNAME LOC
------ ---------- --------- ------ --------- ------ ------ ------ ------
-------------- -------------
7369 SMITH CLERK 7902 17-DEC-80 1200 20 20
RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 30
SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 30
SALES CHICAGO
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 20
RESEARCH DALLAS
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 30
SALES CHICAGO
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 30
SALES CHICAGO
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 10
ACCOUNTING NEW YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 10
ACCOUNTING NEW YORK
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 30
SALES CHICAGO
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 20
RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 1425 30 30
SALES CHICAGO
7902 FORD ANALYST 7566 21-AUG-23 4500 20 20
RESEARCH DALLAS
7934 MILLER CLERK 7782 23-JAN-82 1950 10 10
ACCOUNTING NEW YORK
40
OPERATIONS BOSTON

14 rows selected.

ii. Left Outer Join :


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

-> In this Joins, first it displays matching records from table1,


table2 and un-matched records from Left Side of the
on the Join Condition

SQL> Select * from Emp, Dept where Emp.Deptno= Dept.Deptno(+);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO


DNAME LOC
------ ---------- --------- ------ --------- ------ ------ ------ ------
-------------- -------------
7934 MILLER CLERK 7782 23-JAN-82 1950 10 10
ACCOUNTING NEW YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 10
ACCOUNTING NEW YORK
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 10
ACCOUNTING NEW YORK
7902 FORD ANALYST 7566 21-AUG-23 4500 20 20
RESEARCH DALLAS
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 20
RESEARCH DALLAS
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 20
RESEARCH DALLAS
7369 SMITH CLERK 7902 17-DEC-80 1200 20 20
RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 1425 30 30
SALES CHICAGO
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 30
SALES CHICAGO
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 30
SALES CHICAGO
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 30
SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 30
SALES CHICAGO
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 30
SALES CHICAGO

13 rows selected.

note: There is no un-matched deptnos. from EMP table compare to DEPT.


table
note: if Joining tables are maintainig Primary Key & Foreign key
Relationships then LEFT OUTER JOIN returns Equi Join Output.

iii. FULL OUTER JOIN :


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

-> In this Joins, it displays matching records from table1, table2 and
un-matched records from both tables

full outer join = right outer join + left outer join

ex:-

SQL> Select * from Emp, Dept where Emp.Deptno(+) = Dept.Deptno(+);


Select * from Emp, Dept where Emp.Deptno(+) = Dept.Deptno(+)
*
ERROR at line 1:
ORA-01468: a predicate may reference only one outer-joined table

UNION :
-------

-> it displays matching records from query1 and query2 at one time and
un-matched records from both queries

ex:-

A = { 1, 2, 5 }

B = { 2, 4, 6 }

A U B = { 1, 2, 4, 5, 6 }

SQL> Select * from Emp, Dept where Emp.Deptno= Dept.Deptno(+)


union
Select * from Emp, Dept where Emp.Deptno(+)= Dept.Deptno;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO


DNAME LOC
------ ---------- --------- ------ --------- ------ ------ ------ ------
-------------- -------------
7369 SMITH CLERK 7902 17-DEC-80 1200 20 20
RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30 30
SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30 30
SALES CHICAGO
7566 JONES MANAGER 7839 02-APR-81 4462.5 20 20
RESEARCH DALLAS
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30 30
SALES CHICAGO
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30 30
SALES CHICAGO
7782 CLARK MANAGER 7839 09-JUN-81 3675 10 10
ACCOUNTING NEW YORK
7839 KING PRESIDENT 17-NOV-81 7500 10 10
ACCOUNTING NEW YORK
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30 30
SALES CHICAGO
7876 ADAMS CLERK 7788 12-JAN-83 1650 20 20
RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 1425 30 30
SALES CHICAGO
7902 FORD ANALYST 7566 21-AUG-23 4500 20 20
RESEARCH DALLAS
7934 MILLER CLERK 7782 23-JAN-82 1950 10 10
ACCOUNTING NEW YORK
40
OPERATIONS BOSTON
14 rows selected.

V. SELF JOIN :
--------------

-> To Join the Table Itself is called as Self Join

-> In Self JOIns, Joining tables are same

-> To write self-join queries we must use TABLE ALAISES

SQL> select empno, ename, empno, ename from emp, emp;


select empno, ename, empno, ename from emp, emp
*
ERROR at line 1:
ORA-00918: column ambiguously defined

SQL> select emp.empno, emp.ename, emp.empno, emp.ename from emp, emp;


select emp.empno, emp.ename, emp.empno, emp.ename from emp, emp
*
ERROR at line 1:
ORA-00918: column ambiguously defined

-- waq to display Superiors and their Sub-ordinates

EMP M EMP E
---- ----
EMPNO ENAME MGR EMPNO ENAME MGR
7369 SMITH 7902 7369 SMITH 7902
7566 JONES 7839 7566 JONES 7839
7698 BLAKE 7839 7698 BLAKE 7839
7839 KING 7839 KING
7902 FORD 7566 7902 FORD 7566
7521 JAMES 7698 7521 JAMES 7698

SELECT M.ENAME AS SUPIROR_NAME, E.ENAME AS SUB_ORDINATE


FROM EMP M, EMP E
WHERE M.EMPNO = E.MGR;

Example 2 :
***********

SQL> SELECT * FROM EMP;


EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 21-AUG-23 4500 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

SQL> SELECT M.ENAME AS SUPIROR_NAME, E.ENAME AS SUB_ORDINATE


FROM EMP M, EMP E
WHERE M.EMPNO = E.MGR;

SUPIROR_NA SUB_ORDINA
---------- ----------
JONES FORD
BLAKE JAMES
BLAKE TURNER
BLAKE MARTIN
BLAKE WARD
BLAKE ALLEN
CLARK MILLER
KING CLARK
KING BLAKE
KING JONES
FORD SMITH

11 rows selected.

Oracle 9i, 10g & 11g & 12c Features.


9i Joins:

8 types Joins

1. Natural Join
2. Join with using
3. Join with ON
4. Inner Join

5. Left Outer Join


6. Right Outer Join
7. Full Outer Join

8. Cross Join

i. Select Empno, Ename, Job, Sal, Deptno, Dname, Loc from Emp Natural
Join Dept;
Note: if joining tables there is no similar column name then Natural Join
returns CROSS join OUTPUT.

ii. Select Empno, Ename, Job, Sal, Deptno, Dname Loc from Emp Join Dept
using (Deptno);

Note: if joining tables there is no similar column name then Natural Join
returns CROSS join OUTPUT.

iii. Select E.Empno, E.Ename, E.Job, E.Deptno, D.Dname, D.Loc from Emp E
Join
Dept D ON(E.Deptno=D.Deptno);
iv. Select E.Empno, E.Ename, E.Job, E.Deptno, D.Dname, D.Loc from Emp E
Inner Join
Dept D ON(E.Deptno=D.Deptno);

v. Select E.Empno, E.Ename, E.Job, E.Deptno, D.Dname, D.Loc from Emp E


Left Outer Join Dept D ON(E.Deptno=D.Deptno);

vi. Select E.Empno, E.Ename, E.Job, E.Deptno, D.Dname, D.Loc from Emp E
Right Outer Join Dept D ON(E.Deptno=D.Deptno);

vii. Select E.Empno, E.Ename, E.Job, E.Deptno, D.Dname, D.Loc from Emp E
Full Outer Join Dept D ON(E.Deptno=D.Deptno);

viii. Select Empno, Ename, Job, D.Deptno, Dname, Loc from Emp E Cross
Join Dept D

New Date Functions :

Sysdate : Give Only date in Server Time Zone

CURRENT_DATE

Gives only date in Client Time Zone

Purpose

CURRENT_DATE returns the current date in the session time zone, in a


value in the Gregorian
calendar of datatype DATE.

Examples

The following example illustrates that CURRENT_DATE is sensitive to the


session time zone:

ALTER SESSION SET TIME_ZONE = '-10:0';


ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
SELECT SESSIONTIMEZONE, CURRENT_DATE FROM DUAL;

SESSIONTIMEZONE CURRENT_DATE
--------------- --------------------
-05:00 29-MAY-2000 13:14:03
TimeStamp : Datatype

Used to hold date along with time and automatically

Example :
-------------

Create Table Login_Details


( User_id Varchar2(10),
User_name Varchar2(10),
Login_Time Timestamp,
Logout_Time Timestamp
);

Insert into Login_Details Values('u1','king',sysdate,sysdate+1);

Select * From Login_Details;

To find employee working hours:


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

Select sysdate – Login_time from Login_Details;

To_Timestamp() : Converts given date into Date & Time format

Insert into Login_Details Values


( 'u1','king',sysdate,
to_timestamp('18/11/17 6:00:00 p.m.','dd/mm/yy hh:mi:ss
p.m.')
);

Rename a Column:

Alter table <table_name> RENAME Column <old Column_name> To <new


Column_Name>;

Alter Table Emp RENAME Column Sal to Basic;

Multiple Inserts :

? Supports to insert data into more than one table at a time. But
input must be retrieved from Existing Table.

• Make 3 empty tables same as dept table structure

Create table D1 as select * from dept where rownum is null;


Create table D2 as select * from dept where rownum is null;
Create table D3 as select * from dept where rownum is null;

Insert all into D1 values(deptno,dname,loc)


into D2 values(deptno,dname,loc)
into D3 values(deptno,dname,loc)
select * from Dept;

Insert all into D1 values(1,'ACC','HYD')


into D1 values(2,'RES','SEC')
into D1 values(3,'FIN','HYD')
select * from DUAL;

Conditional Insert :

Insert all
When Deptno<=20 then
into D1 values(deptno, dname, loc)
When Deptno>20 and Deptno<=30 then
into D2 values(deptno,dname,loc)
Else
into D3(Deptno, Dname,Loc) values(Deptno,Dname, Loc)
Select * from Dept;

Merge Statement :

? Merge Statement is used to Merging Two tables information into a


Single Table.

create table copy_emp


(EMPNO NUMBER(4),
ENAME VARCHAR2(10),
SAL NUMBER(7,2),
DEPTNO NUMBER(2)) ;

Insert rows into Copy_emp Table.

Before MERGING :

Copy_Emp c
Empno Ename Sal Deptno
7839 King 5000 10
7566 AAA 2000 30
7369 Smith 800 30

Emp e
Empno Ename Sal Deptno
7566 Jones 3500 10
7902 Allen 3000 20
7521 James 4000 10

Merge into Copy_emp c using Emp e on (c.empno= e.empno)


WHEN MATCHED THEN
UPDATE SET C.ename = e.ename , c.sal= e.sal, c.deptno = e.deptno
WHEN NOT MATCHED THEN
INSERT VALUES (e.empno,e.ename,e.sal,e.deptno);

After Merging:
-------------------
Copy_Emp c
Empno Ename Sal Deptno
7839 King 5000 10
7566 JONES 3500 10
7902 Allen 3000 20
7521 James 4000 10

Teacher 1 :
---------------

19/09/17 9:00am Maths


20/09/17 9:00am Eng
21/09/17 9:00am phys

Teacher 2 :
---------------

20/09/17 9:00am Chem


21/09/17 9:00am phys

NVL2(Expr1, Expr2, Expr3) :

• Expr1 is NOT NULL it manipulates Expr2 otherwise it manipulate


Expr3

Select Ename, Sal, Comm, NVL2(Comm, Sal+Comm,Sal) Net_Pay from Emp;

NULLIF(Expr1, Expr2) :

• If Expr1 & Expr2 results are same then it Returns Null Value,
otherwise Expr1 Result.

Select Nullif(100,50*2), Nullif(1000,50*5), Nullif(7000,3500*2) from


Dual;

Select eName, Nullif(Deptno,10) from Emp order by deptno;

select empno, ename, sal, deptno, Nvl(nullif(deptno,10),50) from emp


order by deptno;

COALESCE(Expr1, Expr2, Expr3,…) :

• Picks the first Not Null Expression Result

Select Coalesce(100+Null, 1000*Null, 500-Null+900,10,7080) from Dual;

-> write a query to declare employee bonus based on following


conditions….

i. If employee is getting commission on commission double bonus


ii. If employee is not getting commission on salary 5% bonus

Select Ename, Sal, Comm,Coalesce(Comm * 2, Sal * 0.05) Bonus from Emp;

Case in Select :

Select Empno, Ename, Job, Sal,


Case
When sal>=5000 then 'Excellent'
When sal>=4000 then 'High'
When sal>=3000 then 'Good'
When sal>=2000 then 'Average'
Else
'Poor Salary'
End as Salary_Status from Emp;

Temporary Tables :

? Used to hold the information for a particular period of time in


logical

Create Global Temporary Table Temp(C1 Date) on commit delete rows;

Insert into Temp values(sysdate);

Select * from Temp;

Commit;

Select * from Temp; -- No Rows

Example 2 :

SQL> Create Global Temporary Table Temp


2 ( Empno Number(4), Ename varchar2(10)) on commit delete rows;

Table created.

SQL> insert into temp values(1001,'king');

1 row created.

SQL> insert into temp values(1002,'scott');

1 row created.

SQL> select * from temp;

EMPNO ENAME
------ ----------
1001 king
1002 scott

SQL> commit;

Commit complete.

SQL> select * from Temp;

no rows selected

Create Global Temporary Table Temp(C1 Date) On Commit Preserve Rows;

Insert into Temp Values(sysdate);

Select * from Temp;

Commit;
Select * from Temp;

Exit; --Temp Table will be empty;

Example 2 :
SQL> Create Global Temporary Table Temp
2 ( Empno Number(4), Ename varchar2(10)) on commit Preserve rows;

Table created.

SQL> insert into temp values(1001,'king');

1 row created.

SQL> insert into temp values(1002,'scott');

1 row created.

SQL> select * from temp;

EMPNO ENAME
------ ----------
1001 king
1002 scott

SQL> commit;

Commit complete.

SQL> select * from temp;

EMPNO ENAME
------ ----------
1001 king
1002 scott

SQL> exit; -- temp will be empty

EXTRACT (DATETIME)

EXTRACT extracts and returns the value of a specified datetime field from
a datetime or interval value expression.

SELECT EXTRACT(YEAR FROM DATE '1998-03-07') FROM DUAL;

EXTRACT(YEARFROMDATE'1998-03-07')
---------------------------------
1998

SQL> SELECT EXTRACT(DAY FROM SYSDATE) FROM DUAL;

EXTRACT(DAYFROMSYSDATE)
-----------------------
22

SQL> SELECT EXTRACT(MONTH FROM SYSDATE) FROM DUAL;

EXTRACT(MONTHFROMSYSDATE)
-------------------------
9

SQL> SELECT EXTRACT(YEAR FROM SYSDATE) FROM DUAL;

EXTRACT(YEARFROMSYSDATE)
------------------------
2017

The following example selects from the sample table hr.employees all
employees who were hired
after 1998:

SELECT ename, empno, hiredate FROM emp WHERE EXTRACT(YEAR FROM


TO_DATE(hiredate, 'DD-MON-YY')) < 1998
ORDER BY hiredate;

-> Write a query to display who are joined in first 15 days from jan and
june in 1981,82, & 83
years.

Select * from Emp where Extract(Day from Hiredate) Between 1 and 15


AND
Extract(Month from Hiredate)
Between 1 and 6
AND
Extract(Year from Hiredate) In (1981,1982,1983);

OLAP FUNCTIONS( ):

Oracle OLAP is an separately licensable option of the Oracle database. It


is only available with Oracle Enterprise Edition.
Some features for processing in oracle include the use of online
analytical processing (olap) upon the data base. Olap features are
useful for datawarehousing, datamart applications and both business users
and IT departments.

ROLLUP:-
A rollup is an extension to the group by clause used to calculate and
return subtotals and grand total as rows of the query efficiently.
It is a group by operation and is used to produce subtotals at any level
of the aggregation. It also calculates a grand total.
If "n" is the number of columns listed in the ROLLUP, there will be n+1
levels of subtotals
Syntax:-
ROLLUP appears in the GROUP BY clause in a SELECT statement. Its form is:
Group by rollup(column1,column2);
or
SELECT ... GROUP BY
ROLLUP(grouping_column_reference_list)

Examples:-
Sql> select deptno,sum(sal) from emp group by rollup(deptno);
Sql> select job,sum(sal) from emp group by rollup(job);

Passing multiple columns to rollup:-


When multiple column are passed to rollup, the rollup,groups the rows
into blocks with same columns
values.
Sql> select deptno, job,sum(sal) salary from emp
group by rollup(deptno,job);
sql> select job, deptno,sum(sal) salary from emp
group by rollup(job,deptno);
sql> SELECT deptno,job, count(*), sum(sal)FROM
emp GROUP BY ROLLUP(deptno,job);

CUBE:-
• it is an extension similar to rollup.
• CUBE enables a SELECT statement to calculate subtotals for all
possible combinations of a group of dimensions.
• It also calculates a grand total.
• If "n" is the number of columns listed in the CUBE, there will be
2n subtotal combinations.

Examples:
Sql> select deptno,job,sum(sal) salary from emp
group by cube(deptno,job);
sql> select job,deptno,sum(sal) salary from emp
group by cube(job,deptno);

SQL> select deptno, job, count(*) from emp


group by cube(deptno,job);

Decode function:-
• DECODE is a SQL function that provides similar functionality to an
IF-THEN-ELSE or Case
statement.
• expression is the value to compare search is the value that is
compared against expression
• result is the value returned, if expression is equal to search
• default is optional. If no matches are found, the decode will
return default. If default is omitted, then the decode statement will
return NULL (no matches found).
• The function has no restriction on the input and output data type.
• It is a single row function.
Syntax
The syntax for the decode function is:
decode(expression, search, result [,search,
result]...[,default] )
Examples:-
SQL> SELECT EMPNO, ENAME, JOB, SAL, DEPTNO,
DECODE(DEPTNO,10,'ACCOUNTING',
20,'RESEARCH',
30,'SALES',

40,'OPERATIONS',

'UNKNOWN' ) AS DNAME
FROM EMP;

SQL> SELECT JOB, Decode(JOB, 'SALESMAN', 'VISIBLE',


'CLERK' ,'INVISIBLE',
'MANAGER','UNKNOWN',
'OTHER') FROM emp;

-- WAQ to find given no. is EVEN or ODD.

SQL> SELECT DECODE( MOD(10,2), 0, 'EVEN', 1, 'ODD' ) FROM DUAL;


DECO
----
EVEN

SQL> SELECT DECODE( MOD(13,2), 0, 'EVEN', 1, 'ODD' ) FROM DUAL;

DEC
---
ODD

DECODE using UPDATE command :


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

-> waq to swap two account balances

SQL> create table bank_db( accno varchar(10), bal number(8,2) );

Table created.

SQL> insert into bank_db values( 'sbi1', 5000 );

1 row created.

SQL> insert into bank_db values( 'sbi2', 10000 );

1 row created.

SQL> commit;

Commit complete.

SQL> select * from bank_db;

ACCNO BAL
---------- ----------
sbi1 5000
sbi2 10000

SQL> UPDATE BANK_DB SET BAL =


DECODE( ACCNO, 'sbi1', ( select bal from bank_db where
accno='sbi2' ),
'sbi2', ( select bal from bank_db where accno='sbi1' )
)
where accno in ('sbi1','sbi2');

2 rows updated.

SQL> select * from bank_db;

ACCNO BAL
---------- ----------
sbi1 10000
sbi2 5000

Ranking functions:-
The different types of ranking functions are
1. Rank() function
2. Dense_rank() function
Rank:-
• The function will compute the rank of each row returned from a
query with respect to the other rows returned by the query, as defined by
the order_by_clause.
• It is possible to have several RANK () OVER functions in a single
SQL statement.
• It returns the rank of items in a group.
• theRANK function can cause non-consecutive rankings if the tested
values are same.
• Rank() leaves a gap in the sequence of rankings in the event of a
tie.
It returns the rank of items in a group.
sql>

Sql> select ename,deptno,sal,rank() over(partition by deptno


order by sal desc) "topsal"
from emp order by deptno,sal desc;

sql> select ename,deptno,sal,rank() over( order by sal desc) "topsal"


from emp order by sal desc ;

DENSE_RANK ( ):
• the DENSE_RANK function will always result in consecutive rankings.
• The DENSE_RANK function acts like the RANK function except that it
assigns consecutive ranks.
Used as an Analytic Function
• As an Analytic function, the DENSE_RANK function returns the rank of
each row of a query with respective to the other rows.

select ename,deptno,sal,dense_rank() over(order by sal desc)


emprank from emp
group by deptno,ename,sal order by emprank;

Sql> select ename, sal,


DENSE_RANK() OVER (PARTITION BY deptno ORDER BY
sal desc)
From emp
where deptno = '20';
Explination:- calculate a rank for each unique salary in the Marketing
department. If two employees had the same salary, the DENSE_RANK function
would return the same rank for both employees.
DENSE_RANK
The DENSE_RANK function acts like the RANK function except that it
assigns consecutive ranks.

Sql> SELECT empno,deptno,sal,


DENSE_RANK() OVER (ORDER BY sal DESC) "rank"
FROM emp ORDER BY SAL DESC;
Sql> select ename,deptno,sal,dense_rank() over(partition by
deptno
order by sal desc) "topsal"
from emp order by deptno,sal desc;

-> write a query to display Nth Maximum salary.

Select Sal, Rank from ( SELECT sal,DENSE_RANK() OVER


(ORDER BY sal Desc) rank
FROM emp)
where rank=&n;

PL/SQL
******

-> PL represents Procedural or Programming Language

-> PL/SQL is introduced in 1990's

-> It is Programming Language and it supports ALL SQL features

-> PL/SQL is embedded with SQL

Main Features of PL/SQL :


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

-> PL/SQL executes a block of statements as a UNIT

-> PL/SQL supports Control Structures and Iteration Control Statements

-> PL/SQL supports User-Defined Datatypes ( composite datatypes )

-> PL/SQL supports to handel the error by using EXCEPTION Handling

-> PL/SQL supports automatic execution of code through DB TRIGGERs

-> PL/SQL supports Sub-Programs( Procedures & Functions )

-> PL/SQL supports Packages

-> PL/SQL supports Object Oriented Programing features

-> PL/SQL supports client side appl.(ex: d2k ) , Server side Appl. and
both Client & Server side applications

What is Block ?

-> Block is a collection of SQL & PL/SQL statements

-> Oracle supports two types of BLOCKS

i. Anonymous Block

ii. Named Block

i. Anonymous Block :
--------------------

-> It is also called as Name Less Block

-> To Save Anonymous block programs user can explicitely save by using
'SAVE' command

-> All anonymous block programs are start with 'DECLARE' or 'BEGIN'
statement
structure of Anonymous Block :
------------------------------

[Declare
<variable_Declaration>;]
Begin
<exec-statements>;
[Exception Block
<exec-statements>;]
End;
/

Simple BLock :
--------------

Begin
<exec-statements>;
End;
/

'/' -> to execute anonymous block program

ii. Named Block :


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

-> this type of block of programs are stored in db permanently

-> Example of Named block programs are...

ex: Stored Procedures, Functions, Triggers & Packages

-> All Named block programs are start with 'CREATE' command

PL/SQL Datatypes :
------------------

-> PL/SQL supports all SQL datatypes and it supports other datatypes
also

i. SCALAR DATATYPES :
---------------------

-> If any datatype can hold one value that type of datatypes are called
as SCALAR datatypes

ex:- CHAR, VARCHAR2, DATE, etc.,

ii. Composite Datatypes :


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

-> if any datatype can hold morethan one value is called as Composite
Datatypes

ex:- PL/SQL RECORD, PL/SQL TABLE, etc.,


III. REFERENCED DATATYPES :
---------------------------

-> These datatypes can reference with other datatype structure

ex:- %TYPE, %ROWTYPE

IV. UN-structured datatypes :


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

-> these datatypes can hold IMAGES, AUDIO FILES AND video files

EX: LOB, BLOB, CLOB, RAW, LONG RAW, BFILE, etc.,

V. BOOLEAN DATATYPES :
-----------------------

-> This datatype can hold either TRUE / FALSE

ex: BOOLEAN

Variable declaration :
----------------------

V_Empid Number(2);

V_Ename Varchar2(10) NOT NULL := 'NARESH IT';

I Number(2) := 1;

FLAG BOOLEAN := TRUE / FALSE;

Pi Constant Number(5,3) := 3.14;

DOJ DATE DEFAULT SYSDATE;

:= -> it is an assignment operator, used to assign the values into


given variable

** PL/SQL supports DML, DRL & TCL commands

** PL/SQL not supported DDL & DCL commands

Comments :
----------

-> Comments are non-executable statments

-> Oracle supports two types commands

i. single line comment

ii. multi-line comment

i. single line comment :


------------------------
-> comment contains single line is called as single line comment

-> In oracle single line comments are represented with '--'

ex:- -- pl/sql block for to display welcome message

ii. Multi-line comment :


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

-> comment contains morethan one line is called as multi-line comment

-> Multi-line comments are represented with /* */

ex:= /* pl/sql block for to display


welcome message *

DBMS_OUTPUT.PUT_LINE( ARG1 ) :
------------------------------

-> It is one of the PL/SQL output statement

-> It accepts single arugment only

-> This output statement sends output to SQL BUFFER

SET SERVEROUTPUT ON :
---------------------

-> It sends output from SQL BUFFER to OUTPUT Screen

-> It is session valid

-- write a PL/SQL Block to display WELCOME message

SQL> BEGIN
DBMS_OUTPUT.PUT_LINE('WELCOME TO PL/SQL');
END;
/

PL/SQL procedure successfully completed.

SQL> SET SERVEROUTPUT ON

SQL> BEGIN
DBMS_OUTPUT.PUT_LINE('WELCOME TO PL/SQL');
END;
/

WELCOME TO PL/SQL

PL/SQL procedure successfully completed.

-- Write a pl/sql block to find sum of two given numbers

Declare
X Number(4) := 100;
Y Number(4) := 300;
BEGIN
DBMS_OUTPUT.PUT_LINE( ( X + Y ) );
END;
/

400

PL/SQL procedure successfully completed.

-- TO TAKE VALUES AT RUN-TIME

Declare
X Number(4) := &X;
Y Number(4) := &Y;
BEGIN
DBMS_OUTPUT.PUT_LINE( ( X + Y ) );
END;
/

SQL> SET VERIFY OFF;

SQL> Declare
X Number(4) := &X;
Y Number(4) := &Y;
BEGIN
DBMS_OUTPUT.PUT_LINE( ( X + Y ) );
END;
/
Enter value for x: 900
Enter value for y: 600
1500

PL/SQL procedure successfully completed.

Declare
X Number(4) := &X;
Y Number(4) := &Y;
BEGIN
DBMS_OUTPUT.PUT_LINE( 'SUM OF TWO NUMBERS = ' || ( X + Y ) );
END;
/

Enter value for x: 900


Enter value for y: 600
SUM OF TWO NUMBERS = 1500

PL/SQL procedure successfully completed.

-- Write a pl/sql block two swap two numbers without using Third Variable

Declare
Num1 Number(4) := 100;
Num2 Number(4) := 200;
Begin
dbms_output.put_line( 'Before Swapping two Numbers : ');
dbms_output.put_line( 'NUM1 = '||NUM1 ); -- 100
dbms_output.put_line( 'NUM2 = '||NUM2 ); -- 200

Num1 := Num1 + Num2; -- num1 := 300


Num2 := Num1 - Num2; -- num2 := 100
Num1 := Num1 - Num2; -- num1 := 200

dbms_output.put_line( 'After Swapping two Numbers : ');


dbms_output.put_line( 'NUM1 = '||NUM1 );
dbms_output.put_line( 'NUM2 = '||NUM2 );

END;
/

Before Swapping two Numbers :


NUM1 = 100
NUM2 = 200
After Swapping two Numbers :
NUM1 = 200
NUM2 = 100

PL/SQL procedure successfully completed.

-- PL/SQL Blocks are Interact with DB TABLES

SELECT..INTO :
--------------

-> It is used to copies DB Column values into PL/SQL variables

-> No.of DB Columns should be matched with NO.OF PL/SQL Variables and
corresponding columns datatypes should be same.

syn:-

Select Col1, Col2,... Into <var1>, <var2>,... from <table_name> WHERE


<condition>;

Example :
---------

-- write a pl/sql block to display 7788 employee name & salary

Declare
v_ename varchar2(10);
v_sal Number;
Begin
Select Ename, Sal Into v_Ename, v_sal from Emp Where Empno = 7788;
dbms_output.put_line( v_ename );
dbms_output.put_line( v_sal );
End;
/

SCOTT
3000

PL/SQL procedure successfully completed.


-- write a pl/sql block to find given EMPLOYEE NET SALARY

DECLARE
V_EMPNO NUMBER(4) := &EMPNO;
V_SAL NUMBER(8,2);
V_COMM NUMBER(6,2);
BEGIN
SELECT SAL, COMM INTO V_SAL, V_COMM FROM EMP WHERE EMPNO = V_EMPNO;
DBMS_OUTPUT.PUT_LINE( 'NET SALARY RS.= ' || ( V_SAL + NVL(V_COMM,0) ) );
END;
/

Enter value for empno: 7521


NET SALARY RS.= 1750

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7788
NET SALARY RS.= 3000

PL/SQL procedure successfully completed.

-- write a pl/sql block to input employee no. and display corresponding


employee empno, name, job, salary & deptno

Declare
v_empno number(4);
v_ename varchar2(20);
v_job varchar2(20);
v_sal number(5,2);
v_deptno number(2);
Begin
Select Empno, Ename, Job, Sal, Deptno Into
v_empno, v_ename, v_job, v_sal,
v_deptno
From Emp
Where Empno = &Empno;
dbms_output.put_line(' Employee No : '|| v_Empno);
dbms_output.put_line(' Employee Name : '|| v_Ename);
dbms_output.put_line(' Employee Job : '|| v_Job);
dbms_output.put_line(' Employee Salary : '|| v_Sal);
dbms_output.put_line(' Employee Deptno : '|| v_Deptno);
End;
/

Enter value for empno: 7788


Employee No : 7788
Employee Name : SCOTT
Employee Job : ANALYST
Employee Salary : 3000
Employee Deptno : 20

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7521
Employee No : 7521
Employee Name : WARD
Employee Job : SALESMAN
Employee Salary : 1250
Employee Deptno : 30

PL/SQL procedure successfully completed.

REFERENCED DATATYPES :
----------------------

-> These datatypes are used to declare variable datatypes dynamically


accordinng corresponding COLUMN or TABLE Structure

-> There are two types REFERENCED datatypes

i. column type ( %type )

ii. rowtype or tabletype( %rowtype )

i. column type ( %type ) :


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

-> This attribute used to declare variable datatype dynamically


according corresponding Column Structure

syn:-

<variable_name> <table_name>.<column_name>%type;

ex:-

v_empno emp.empno%type;

example program :
-----------------

-- write a pl/sql block to input employee no. and display corresponding


employee empno, name, job, salary & deptno

Declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_job emp.job%type;
v_sal emp.sal%type;
v_deptno emp.deptno%type;
Begin
Select Empno, Ename, Job, Sal, Deptno Into
v_empno, v_ename, v_job, v_sal,
v_deptno
From Emp
Where Empno = &Empno;
dbms_output.put_line(' Employee No : '|| v_Empno);
dbms_output.put_line(' Employee Name : '|| v_Ename);
dbms_output.put_line(' Employee Job : '|| v_Job);
dbms_output.put_line(' Employee Salary : '|| v_Sal);
dbms_output.put_line(' Employee Deptno : '|| v_Deptno);
End;
/

Enter value for empno: 7521


Employee No : 7521
Employee Name : WARD
Employee Job : SALESMAN
Employee Salary : 1875
Employee Deptno : 30

PL/SQL procedure successfully completed.

ii. rowtype or tabletype( %rowtype ) :


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

-> This attribute is used to declare variable datatype dynamically


according entire table structure

syn:-

<variable_name> <table_name>%rowtype;

ex:-

e_rec emp%rowtype;

Example Program :
-----------------

-- write a pl/sql block to input a employee no. and display


corresponding employee entire record

Declare
e emp%rowtype;
Begin
select * into e from emp where empno = &empno;
dbms_output.put_line( e.empno );
dbms_output.put_line( e.ename );
dbms_output.put_line( e.job );
dbms_output.put_line( e.mgr );
dbms_output.put_line( e.hiredate );
dbms_output.put_line( e.sal );
dbms_output.put_line( e.comm );
dbms_output.put_line( e.deptno );
End;
/

Enter value for empno: 7521


7521
WARD
SALESMAN
7698
22-FEB-81
1875
500
30

PL/SQL procedure successfully completed.


or

-- write a pl/sql block to input a employee no. and display


corresponding employee entire record

Declare
e emp%rowtype;
Begin
select * into e from emp where empno = &empno;
dbms_output.put_line( e.empno ||' '|| e.ename ||' '|| e.job ||' '||e.mgr
||' ' || e.hiredate ||' '||e.sal||' '||

e.comm ||' '||e.deptno );


End;
/

Enter value for empno: 7521


7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30

PL/SQL procedure successfully completed.

Rowtype Attributes are using INSERT & UPDATE statements :


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

-- write a pl/sql block to insert data into DEPT. table

Declare
d dept%rowtype;
Begin
d.deptno := 50;
d.dname := 'MATHS';
d.loc := 'HYD';
Insert into Dept values D;
dbms_output.put_line(' Record Inserted.');
End;
/

Record Inserted.

PL/SQL procedure successfully completed.

SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD

UPDATE Command :
----------------

Declare
d dept%rowtype;
Begin
d.deptno := 50;
d.dname := 'ENG';
d.loc := 'SEC';
update dept set row = D where deptno = d.deptno;
dbms_output.put_line('record updated.');
end;
/

record updated.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 ENG SEC

CONTROL STRUCTURES :
--------------------

-> Control Structures are used to control flow of the programs

-> Oracle supports 4 types control structures

I. Conditional Control Structures

II. Branching Control Structures

III. Iteration Control Structures

IV. Un-Conditional Control Structures

I. Conditional Control Structures :


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

-> These are classified into 4 types

a. simple if

b. if..else

c. nested if

d. elsif lader

a. simple if :
--------------

-> It contains only TRUE block

syn:-

if <condition> then
<exec-statements>; -- true block
end if;

ex:-

declare
flag boolean := &flag;
Begin
if Flag = true then
dbms_output.put_line('we r in True Block');
end if;
dbms_output.put_line('end of the program');
End;
/

Enter value for flag: TRUE


we r in True Block
end of the program

PL/SQL procedure successfully completed.

Enter value for flag: FALSE


end of the program

PL/SQL procedure successfully completed.

ii. if..else :
--------------

-> it contains both TRUE & FALSE blocks

syn:-

if <cond.> then
<exec-statements>; -- True Block
else
<exec-statements>; -- False Block
end if;

example :
---------

-- write a pl/sql block to find given no. is even or odd

Declare
Num Number(4) := &Num;
Begin
if Mod( Num, 2 ) = 0 then
dbms_output.put_line('even');
else
dbms_output.put_line('odd');
end if;
dbms_output.put_line('end of the program');
End;
/

Enter value for num: 19


odd
end of the program
PL/SQL procedure successfully completed.

SQL> /
Enter value for num: 12
even
end of the program

PL/SQL procedure successfully completed.

iii. Nested if :
----------------

-> If within the if is called as Nested if

syn:-

if <cond.> then
if <cond.> then
<exec-statements>;
else
<exec-statements>;
end if;
else
if <cond.> then
<exec-statements>;
else
<exec-statements>;
end if;
end if;

-- write a pl/sql block to declare employee bonus based on following


conditions

i. if employee type is 'permanent' & experience >=10 years then


50% bonus

ii. if employee type is 'permanent' & experience < 10 years


then 30% bonus

iii. if employee type is 'temporary' & experience >= 10 years


then 20% bonus

iv. if employee type is 'temporary' & experience < 10 years


then 15% bonus

iii. Nested if :
----------------

-> If within the if is called as Nested if

syn:-

if <cond.> then
if <cond.> then
<exec-statements>;
else
<exec-statements>;
end if;
else
if <cond.> then
<exec-statements>;
else
<exec-statements>;
end if;
end if;

-- write a pl/sql block to declare employee bonus based on following


conditions

i. if employee type is 'permanent' & experience >=10 years then


50% bonus

ii. if employee type is 'permanent' & experience < 10 years


then 30% bonus

iii. if employee type is 'temporary' & experience >= 10 years


then 20% bonus

iv. if employee type is 'temporary' & experience < 10 years


then 15% bonus

Declare
v_emptype char(1) := '&emp_type'; -- 't'
v_exp Number(4) := &exp; -- 9
Begin
if v_emptype='p' then
if v_exp >=10 then
dbms_output.put_line(' Employ will get 50% Bonus.');
else
dbms_output.put_line(' Employ will get 30% Bonus.');
end if;
else
if v_exp >=10 then
dbms_output.put_line(' Employ will get 20% Bonus.');
else
dbms_output.put_line(' Employ will get 15% Bonus.');
end if;
end if;
End;
/

Enter value for emp_type: p


Enter value for exp: 12
Employ will get 50% Bonus.

PL/SQL procedure successfully completed.

SQL> /
Enter value for emp_type: p
Enter value for exp: 9
Employ will get 30% Bonus.

PL/SQL procedure successfully completed.

SQL> /
Enter value for emp_type: t
Enter value for exp: 14
Employ will get 20% Bonus.

PL/SQL procedure successfully completed.

SQL> /
Enter value for emp_type: t
Enter value for exp: 3
Employ will get 15% Bonus.

PL/SQL procedure successfully completed.

iv. ELSIF LADER :


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

-> by using this control structure we can check multiple conditions


continuously

syn:-

if <cond.> then
<exec-statements>;
elsif <cond.> then
<exec-statements>;
elsif <cond.> then
<exec-statements>;
.
.
else
<exec-statements>;
End if;

Example :
---------

-- write a pl/sql block to input employ no. and display corresponding


employee DEPT. NAME

Declare
v_empno emp.empno%type := &empno;
v_deptno emp.deptno%type;
Begin
Select deptno into v_deptno from emp where empno = v_empno;
if v_deptno=10 then
dbms_output.put_line('ACCOUNTING DEPT.');
elsif v_deptno=20 then
dbms_output.put_line('RESEARCH DEPT.');
elsif v_deptno=30 then
dbms_output.put_line('SALES DEPT.');
elsif v_deptno=40 then
dbms_output.put_line('OPERATIONS DEPT.');
else
dbms_output.put_line('UNKNOWN DEPT.');
end if;
End;
/

Enter value for empno: 7839


ACCOUNTING DEPT.

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7369
RESEARCH DEPT.

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7521
SALES DEPT.

PL/SQL procedure successfully completed.


End;
/

II. Branching Control Structure :


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

-> this control structure is also called as JUMP control Structure

i. CASE

syn:-

CASE <variable/expression>
WHEN <cond.> then
<exec-statements>;
WHEN <cond.> then
<exec-statements>;
WHEN <cond.> then
<exec-statements>;
ELSE
<exec-statements>;
END CASE;

Example :
---------

Declare
color char(1) := '&color';
Begin
Case color
when 'r' then
dbms_output.put_line('u r selected red color.');
when 'y' then
dbms_output.put_line('u r selected yellow color.');
when 'b' then
dbms_output.put_line('u r selected black color.');
else
dbms_output.put_line('your selection is wrong plz. try again....');
end case;
End;
/

Enter value for color: r


u r selected red color.
PL/SQL procedure successfully completed.

SQL> /
Enter value for color: b
u r selected black color.

PL/SQL procedure successfully completed.

SQL> /
Enter value for color: x
your selection is wrong plz. try again....

PL/SQL procedure successfully completed.

III. ITERATION CONTROL STRUCTURES :


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

-> the statements are executed 'n' no.of times until given condition
become TRUE / FALSE

-> pl/sql supports 4 types of Iteration control structures

i. simple loop

ii. while loop

iii. for loop

iv. for cursor

i. simple loop :
-----------------

-> It is an Infinite loop

syn:-

Loop
<exec-statements>;
End Loop;

example:
--------

Begin
Loop
dbms_output.put_line( 'Welcome' );
End Loop;
End;
/

How to break simple loop :


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

-> to break the simple loop we have two syntaxes

i. if <cond.> then
Exit;
end if;
example :
---------

-- pl/sql block for to display WELCOME message 10 times

Declare
i number(4) := 1;
Begin
Loop
if i >10 then
exit;
end if;
dbms_output.put_line('Welcome');
i := i + 1;
End Loop;
dbms_output.put_line('end of the program');
End;
/

Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
end of the program

PL/SQL procedure successfully completed.

syn 2:-

EXIT WHEN <cond.>; -- EXIT is executed when Condition becomes TRUE

example :
---------

-- pl/sql block for to display WELCOME message 10 times

Declare
i number(4) := 1;
Begin
Loop
EXIT WHEN i >10;
dbms_output.put_line('Welcome');
i := i + 1;
End Loop;
dbms_output.put_line('end of the program');
End;
/

Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
Welcome
end of the program

PL/SQL procedure successfully completed.

ii. WHILE LOOP :


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

-> In this control structure first it checks the condition, if


condition is TRUE then LOOP executed

syn:-

WHILE ( <cond.> )
LOOP
<exec-statements>;
Incr/Decr;
END LOOP;

Example :

-- pl/sql block for to display 1 to 10 natural numbers

Declare
i Number(4) :=1;
Begin
While( i <=10 )
Loop
dbms_output.put_line( i );
i := i + 1;
End Loop;
End;
/

1
2
3
4
5
6
7
8
9
10

PL/SQL procedure successfully completed.

ii. WHILE LOOP :


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

-> In this control structure first it checks the condition, if


condition is TRUE then LOOP executed

syn:-

WHILE ( <cond.> )
LOOP
<exec-statements>;
Incr/Decr;
END LOOP;

Example :

-- pl/sql block for to display 1 to 10 natural numbers

Declare
i Number(4) :=1;
Begin
While( i <=10 )
Loop
dbms_output.put_line( i );
i := i + 1;
End Loop;
End;
/

1
2
3
4
5
6
7
8
9
10

PL/SQL procedure successfully completed.

-- to display with REVERSE order

declare
i Number(4) := 10;
Begin
While( i >=1 )
Loop
dbms_output.put_line( i );
i := i - 1;
End Loop;
End;
/

10
9
8
7
6
5
4
3
2
1

PL/SQL procedure successfully completed.

-- PL/SQL block for to display Multiplication TABLE :


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

5*1=5
5*2=10
.
.
5*10=50

Declare
N Number(4) := &N; -- 5
i Number(4) := 1;
Begin
While( i <= 10 )
Loop
dbms_output.put_line( N || '*' || i || '=' || (N*i) );
i := i + 1;
End Loop;
End;
/

Enter value for n: 5


5*1=5
5*2=10
5*3=15
5*4=20
5*5=25
5*6=30
5*7=35
5*8=40
5*9=45
5*10=50

PL/SQL procedure successfully completed.

SQL> /
Enter value for n: 19
19*1=19
19*2=38
19*3=57
19*4=76
19*5=95
19*6=114
19*7=133
19*8=152
19*9=171
19*10=190

PL/SQL procedure successfully completed.

iii. FOR LOOP :


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

-> In FOR LOOP, by default Index variable value is incremented by 1

syn:-

FOR <index_variable> IN <start_value>..<end_value>


LOOP
<exec-statements>;
END LOOP;

example :
---------

-- pl/sql block for to display 1 to 10 numbers

Begin
FOR I in 1..10
LOOP
dbms_output.put_line( i );
END LOOP;
END;
/

1
2
3
4
5
6
7
8
9
10

PL/SQL procedure successfully completed.

-- REVERSE ORDER

Begin
FOR I in REVERSE 1..10
LOOP
dbms_output.put_line( i );
END LOOP;
END;
/

10
9
8
7
6
5
4
3
2
1

PL/SQL procedure successfully completed.

iv. FOR CURSOR :


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

-> Cursors using FOR LOOP is called as FOR CURSOR

IV. UN-CONDITIONAL CONTROL Structure :


--------------------------------------
-> Pl/sql supports two types of un-conditional control structures

i. GOTO ii. EXIT

Example :
---------

-- pl/sql block for to display given no. is +VE or -VE

declare
N Number(4) := &N;
begin
if N >0 then
goto pos;
else
goto neg;
end if;

<<pos>>
dbms_output.put_line( 'Given No. is Positive.');
goto endl;
<<neg>>
dbms_output.put_line( 'Given No. is Negative.');
goto endl;
<<endl>>
dbms_output.put_line( 'End of the Program. ');
End;
/

Enter value for n: 10


Given No. is Positive.
End of the Program.

PL/SQL procedure successfully completed.

SQL> /
Enter value for n: -4
Given No. is Negative.
End of the Program.

PL/SQL procedure successfully completed.

CURSORS :
---------

declare
v_ename emp.ename%type;
begin
Select ename into v_ename from emp where deptno=10;
dbms_output.put_line( v_ename );
End;
/

declare
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4
note: v_ename variable can hold only one value at a time

CURSORS :
----------

-> It is one of the PRIVATE context area

-> It creates a temporary and it holds transactional data

-> Cursors are created based SELECT statement output

-> In pl/sql block whenever SELECT statement returns more than one row
then to use CURSORS

-> Basically cursors are two types

I. STATIC CURSOR

II. DYNAMIC CURSOR

I. STATIC CURSOR :
------------------

-> While declaring the cursor to provide SELECT statement is called as


STATIC CURSOR

-> Static cursors are classified into two types

a. Explicit Cursor : It is defined by user

b. Implicit Cursor : It is defined by oracle

a. Explicit Cursors :
---------------------

-> To write explicit cursors we must know cursor operations &


attributes

Cursor Operations :
-------------------

i. Declaring cursor :
---------------------

-> In declaration part we can declare the cursor

syn:-

CURSOR <cursor_name>
Is
<Select statement>;

ex:- Cursor C1 is select ename from emp;

ii. OPEN <cursor_name> :


------------------------
-> It opens the cursor

-> Memory is allocated after openend.

ex:- Open C1;

iii. FETCH <cursor_name> INTO <pl/sql variables> :


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

-> It fetches data from cursor into PL/SQL variables

-> The Fetch Statement fetches one record at a time

ex:- Fetch C1 into v_ename;

iv. CLOSE <cursor_name> :


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

-> It closes the cursor

-> Allocated memory will be de-allocated

ex:- CLOSE C1;

CURSOR ATTRIBUTES :
-------------------

-> Cursor Attributes are used to RETURNs status of the cursor

syn:-

<cursor_name>%<attribute>;

i. %isopen :
------------

-> It returns TRUE, when cursor opened successfully

ii. %found :
------------

-> It returns True, when cursor contains data

iii. %notfound :
----------------

-> It returns True, When cursor doesn't find any data

iv. %rowcount :
---------------

-> It returns Number

-> No.of Fetch statements executed

Example :
----------
-- pl/sql block for to demonistrate cursor operations & attributes

Declare
cursor my_cur is select ename from emp;
v_ename emp.ename%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('Cursor Opened Successfully.');
end if;
Fetch my_cur into v_ename;
dbms_output.put_line( v_ename );
Fetch my_cur into v_ename;
dbms_output.put_line( v_ename );
Fetch my_cur into v_ename;
dbms_output.put_line( v_ename );
close my_cur;
end;
/

Cursor Opened Successfully.


SMITH
ALLEN
WARD

PL/SQL procedure successfully completed.

NOTE: above program displays first three employee names only. To display
all employee names then to use
cursor using LOOPs

CURSOR using SIMPLE LOOP :


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

-- write a cursor program to display all employee names from emp table

Declare
cursor my_cur is select ename from emp;
v_ename emp.ename%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('Cursor Opened Successfully.');
end if;
LOOP
Fetch my_cur into v_ename;
EXIT WHEN MY_CUR%NOTFOUND;
dbms_output.put_line( v_ename );
END LOOP;
Close my_cur;
End;
/

Cursor Opened Successfully.


SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
KING
TURNER
ADAMS
JAMES
FORD
MILLER

PL/SQL procedure successfully completed.

-- write a cursor program to increment all employee salaries based on


below conditions.

if employee job is ANALYST/MANAGER then 30% increment

if employee job is SALESMAN/CLERK then 20% increment

for other jobs No Increment.

and Incremented details should be stored in EMPLOYEE AUDIT TABLE

Table creation :
----------------

Create table emp_audit( empno number(4), incr_date date, incr_amt


number(8,2) );

program :
---------

declare
cursor e_cur is select empno, job, sal from emp;
v_empno emp.empno%type;
v_job emp.job%type;
v_sal emp.sal%type;
v_incr_sal Number;
Begin
Open e_cur;
Loop
fetch e_cur into v_empno, v_job, v_sal;
exit when e_cur%notfound;
if v_job in ( 'ANALYST','MANAGER' ) then
v_incr_sal := v_sal * 0.3;
elsif v_job in ( 'SALESMAN','CLERK' ) then
v_incr_sal := v_sal * 0.2;
else
v_incr_sal := 0;
end if;
insert into emp_audit values ( v_empno, sysdate, v_incr_sal );
Update emp set sal = sal + v_incr_sal where empno = v_empno;
End Loop;
dbms_output.put_line( 'Salaries Incremented successfully.');
Close e_cur;
End;
/

Salaries Incremented successfully.

PL/SQL procedure successfully completed.


SQL> select * from emp_audit;

EMPNO INCR_DATE INCR_AMT


------ --------- --------
7369 05-OCT-23 240
7499 05-OCT-23 480
7521 05-OCT-23 375
7566 05-OCT-23 1338.8
7654 05-OCT-23 375
7698 05-OCT-23 1282.5
7782 05-OCT-23 1102.5
7839 05-OCT-23 0
7844 05-OCT-23 450
7876 05-OCT-23 330
7900 05-OCT-23 285
7902 05-OCT-23 1350
7934 05-OCT-23 390

13 rows selected.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1440 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2880 300 30
7521 WARD SALESMAN 7698 22-FEB-81 2250 500 30
7566 JONES MANAGER 7839 02-APR-81 5801.3 20
7654 MARTIN SALESMAN 7698 28-SEP-81 2250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 5557.5 30
7782 CLARK MANAGER 7839 09-JUN-81 4777.5 10
7839 KING PRESIDENT 17-NOV-81 7500 10
7844 TURNER SALESMAN 7698 08-SEP-81 2700 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1980 20
7900 JAMES CLERK 7698 03-DEC-81 1710 30
7902 FORD ANALYST 7566 21-AUG-23 5850 20
7934 MILLER CLERK 7782 23-JAN-82 2340 10

13 rows selected.

CURSOR using WHILE LOOP :


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

-- write a cursor progrm to dispaly top-5 employee maximum salaries

Declare
cursor c1 is select sal from emp order by sal desc;
v_sal emp.sal%type;
Begin
Open c1;
fetch c1 into v_sal;
While( c1%rowcount<=5 )
Loop
dbms_output.put_line( v_sal );
fetch c1 into v_sal;
End Loop;
close c1;
End;
/

7500
5850
5801.25
5557.5
4777.5

PL/SQL procedure successfully completed.

-- write a cursor program to display alternate records( even records )

-- write a cursor program to display empno, ename, sal & deptno

-- writea cursor program to display DEPT. table records

ii. IMPLICIT CURSORS :


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

-> These cursors are defined by oracle implicitely

-> Implicit cursors are also supports Attributes

SQL%FOUND :
-----------

-> It returns TRUE, atleast one record is SELECTED/MANIPULATED

SQL%NOTFOUND:
-------------

-> It returns TRUE, atleast NO record is SELECTED/MANIPULATED

SQL%ROWCOUNT :
--------------

-> It returns NUMBER, no.of Records are SELECTED/MANIPULATED

ii. IMPLICIT CURSORS :


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

-> These cursors are defined by oracle implicitely

-> Implicit cursors are also supports Attributes

SQL%FOUND :
-----------

-> It returns TRUE, atleast one record is SELECTED/MANIPULATED

SQL%NOTFOUND:
-------------

-> It returns TRUE, atleast NO record is SELECTED/MANIPULATED

SQL%ROWCOUNT :
--------------

-> It returns NUMBER, no.of Records are SELECTED/MANIPULATED

Ex:-

Delete from Emp where deptno=10;

ex2:-

Begin
Update emp set sal = sal + 100 where deptno=50;
if SQL%FOUND then
dbms_output.put_line( 'Employ Salaries Incremented Successfully.');
else
dbms_output.put_line( 'Employ Records Not Found.');
end if;
End;
/

Employ Salaries Incremented Successfully.

PL/SQL procedure successfully completed.

II. DYNAMIC CURSOR / REF CURSOR :


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

-> To declare the cursor without using SELECT statement

-> SELECT statement will be provided at the time of opening the cursor

syn:-

TYPE <cursor_name> IS REF CURSOR;

ex:-

declare
TYPE R_CUR IS REF CURSOR;
v_cur r_cur;
v_empno emp.empno%type;
v_exp number;
v_hiredate emp.hiredate%type;
v_dname dept.dname%type;
Begin
Open v_cur for select empno, hiredate from emp;
loop
fetch v_cur into v_empno, v_hiredate;
exit when v_cur%notfound;
v_exp := round( (sysdate - v_hiredate)/365);
dbms_output.put_line( v_empno || ' Employee Experience is ' ||
v_exp|| ' Years.');
end loop;
close v_cur;
dbms_output.put_line('*********************************************');
open v_cur for select empno, dname from emp, dept where emp.deptno =
dept.deptno;
loop
fetch v_cur into v_empno, v_dname ;
exit when v_cur%notfound;
dbms_output.put_line( v_empno || ' Employee working in ' || v_dname
|| ' Dept.');
end loop;
close v_cur;
End;
/

7369 Employee Experience is 43 Years.


7499 Employee Experience is 43 Years.
7521 Employee Experience is 43 Years.
7566 Employee Experience is 43 Years.
7654 Employee Experience is 42 Years.
7698 Employee Experience is 42 Years.
7782 Employee Experience is 42 Years.
7788 Employee Experience is 41 Years.
7839 Employee Experience is 42 Years.
7844 Employee Experience is 42 Years.
7876 Employee Experience is 41 Years.
7900 Employee Experience is 42 Years.
7902 Employee Experience is 42 Years.
7934 Employee Experience is 42 Years.
*********************************************
7369 Employee working in RESEARCH Dept.
7499 Employee working in SALES Dept.
7521 Employee working in SALES Dept.
7566 Employee working in RESEARCH Dept.
7654 Employee working in SALES Dept.
7698 Employee working in SALES Dept.
7782 Employee working in ACCOUNTING Dept.
7788 Employee working in RESEARCH Dept.
7839 Employee working in ACCOUNTING Dept.
7844 Employee working in SALES Dept.
7876 Employee working in RESEARCH Dept.
7900 Employee working in SALES Dept.
7902 Employee working in RESEARCH Dept.
7934 Employee working in ACCOUNTING Dept.

PL/SQL procedure successfully completed.

iv. FOR CURSOR :


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

-> Cursors using FOR LOOP is called as FOR CURSOR

-> In FOR CURSORS

i. for loop open the cursor

ii. fetch the records into Index variable

iii. after fetch the all records then FOR LOOP close the
cursor

ex:-

-- to display employee records by using FOR CURSOR

Declare
cursor c1 is select * from emp;
Begin
For i in c1
Loop
dbms_output.put_line( i.empno ||' '||i.ename||' '||i.job||'
'||i.hiredate||' '||i.sal ||' '||i.deptno );
End loop;
End;
/

7369 SMITH CLERK 17-DEC-80 900 20


7499 ALLEN SALESMAN 20-FEB-81 1600 30
7521 WARD SALESMAN 22-FEB-81 1250 30
7566 JONES MANAGER 02-APR-81 3075 20
7654 MARTIN SALESMAN 28-SEP-81 1250 30
7698 BLAKE MANAGER 01-MAY-81 2850 30
7782 CLARK MANAGER 09-JUN-81 2450 10
7788 SCOTT ANALYST 09-DEC-82 3100 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 08-SEP-81 1500 30
7876 ADAMS CLERK 12-JAN-83 1200 20
7900 JAMES CLERK 03-DEC-81 950 30
7902 FORD ANALYST 03-DEC-81 3100 20
7934 MILLER CLERK 23-JAN-82 1300 10

PL/SQL procedure successfully completed.

SQL> declare
2 v_ename emp.ename%type;
3 begin
4 select ename into v_ename from emp where empno=7788;
5 dbms_output.put_line( v_ename );
6 End;
7 /
SCOTT

PL/SQL procedure successfully completed.

SQL> declare
2 v_ename emp.ename%type;
3 begin
4 select ename into v_ename from emp where empno=9000;
5 dbms_output.put_line( v_ename );
6 End;
7 /
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4

EXCEPTION HANDLING :
--------------------

-> PL/SQL errors are termed as EXCEPTIONS

-> by using EXCEPTION Handling we can handel Run-time errors


-> In PL/SQL run-time errors are classified into three types

I. PRE-DEFINED Exceptions

II. USER-DEFINED Exceptions

III. Non-PREDEFINED Exceptions

I. PRE-DEFINED Exceptions :
---------------------------

-> In this exceptions...

i. Exception name is defined oracle

ii. activated by oracle

iii. solution is provided by USER

EXCEPTION HANDLING :
--------------------

-> PL/SQL errors are termed as EXCEPTIONS

-> by using EXCEPTION Handling we can handel Run-time errors

-> In PL/SQL run-time errors are classified into three types

I. PRE-DEFINED Exceptions

II. USER-DEFINED Exceptions

III. Non-PREDEFINED Exceptions

I. PRE-DEFINED Exceptions :
---------------------------

-> While executing the program oracle returns some common error
messages are called as pre-defined exceptions

-> In this exceptions...

i. Exception name is defined oracle

ii. activated by oracle

iii. solution is provided by USER

ex:-

-- pl/sql block for to handle NO DATA FOUND error

SQL> declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=9000;
dbms_output.put_line( v_ename );
Exception
when NO_DATA_FOUND then
dbms_output.put_line( 'Employee Record Not Found.');
End;
/

Employee Record Not Found.

PL/SQL procedure successfully completed.

example 2:
----------

TOO_MANY_ROWS : This exception name is used to handle, in pl/sql block


whenever SELECT..INTO clause returns morethan one record

Declare
v_ename emp.ename%type;
Begin
select ename into v_ename from emp;
dbms_output.put_line( v_ename );
End;
/

Declare
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4

Declare
v_ename emp.ename%type;
Begin
select ename into v_ename from emp;
dbms_output.put_line( v_ename );
Exception
when TOO_MANY_ROWS then
dbms_output.put_line( 'Morethan one record found.');
End;
/

Morethan one record found.

PL/SQL procedure successfully completed.

Example 3 :
***********

ZERO_DIVIDE :
-------------

-> Used to handle if any value is DIVIDE with 0

Begin
dbms_output.put_line( 'Division of Two Numbers = '|| ( &x / &y ) );
exception
when zero_divide then
dbms_output.put_line('Divisor should not be equals to 0.');
End;
/
Enter value for x: 10
Enter value for y: 2
Division of Two Numbers = 5

PL/SQL procedure successfully completed.

SQL> /
Enter value for x: 10
Enter value for y: 0
Divisor should not be equals to 0.

PL/SQL procedure successfully completed.

Example 4 :
-----------

VALUE_ERROR :
-------------

-> Used to handle, if inserting value is bigger then given size

Declare
str varchar2(5);
Begin
str := 'NARESH IT';
dbms_output.put_line( str );
End;
/

Declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too
small
ORA-06512: at line 4

Declare
str varchar2(5);
Begin
str := 'NARESH IT';
dbms_output.put_line( str );
Exception
when VALUE_ERROR then
dbms_output.put_line( 'Inputing data is Exceeds given variable
size...');
End;
/

Inputing data is Exceeds given variable size...

PL/SQL procedure successfully completed.

Example 5:
----------

INVALID_NUMBER :
----------------

-> Used to handle, try to convert STRING to NUMBER datatype


SQL> Begin
Insert into dept values ( 'MATHS', 50, 'HYD');
END;
/
Begin
*
ERROR at line 1:
ORA-01722: invalid number
ORA-06512: at line 2

SQL> Begin
Insert into dept values ( 'MATHS', 50, 'HYD');
Exception
when INVALID_NUMBER then
dbms_output.put_line( 'Insert Appropriate Data into Table.');
END;
/

Insert Appropriate Data into Table.

PL/SQL procedure successfully completed.

Example 6 :
-----------

CURSOR_ALREADY_OPEN :
---------------------

-> Used to handel, to re-open the cursor without Close

Example :
---------

Declare
cursor c1 is select ename from emp;
Begin
open c1;
open c1;
close c1;
End;
/

Declare
*
ERROR at line 1:
ORA-06511: PL/SQL: cursor already open
ORA-06512: at line 2
ORA-06512: at line 5

Declare
cursor c1 is select ename from emp;
Begin
open c1;
open c1;
close c1;
Exception
when cursor_already_open then
dbms_output.put_line( 'First close the cursor without re-open');
End;
/

First close the cursor without re-open

PL/SQL procedure successfully completed.

II. USER-DEFINED EXCEPTIONS :


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

-> According to CLIENT/END-USER requirement Developer raised error


messages are called as USER-DEFINED EXCEPTIONS

-> In this Exceptions....

i. Exception Name is defined by User

ii. Activated by User ( by using RAISE statement )

iii. Solution is provided by User

-> Oracle provided two pre-defined PROCEDURES

a. RAISE

b. RAISE_APPLICATION_ERROR

a. RAISE :
-----------

-> It is one of the pre-defined procedures and used throws user defined
exception name into exception block

syn:-

RAISE <user-defined_exception-name>;

b. RAISE_APPLICATION_ERROR :
----------------------------

-> This procedure is used to displays ERROR messages with ERROR code

-> It accepts two arguments

syntax:
-------

RAISE_APPLICATION_ERROR( user_defined_error_code,
user_defined_error_message );

-> Oracle provided user_defined_error_codes from -20001 to -20999

example :
---------

-- write a pl/sql block to restrict DML commands on Every WEEK-ENDs


Declare
holiday Exception;
Begin
if to_char(sysdate,'dy') in ( 'sat','sun') then
RAISE holiday;
else
dbms_output.put_line('DML Transactions are Allows.');
end if;
Exception
when holiday then
raise_application_error( -20001, 'Week-Ends Transactions are not
allowed.');
End;
/

Declare
*
ERROR at line 1:
ORA-20001: Week-Ends Transactions are not allowed.
ORA-06512: at line 11

II. USER-DEFINED EXCEPTIONS :


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

-> According to CLIENT/END-USER requirement Developer raised error


messages are called as USER-DEFINED EXCEPTIONS

-> In this Exceptions....

i. Exception Name is defined by User

ii. Activated by User ( by using RAISE statement )

iii. Solution is provided by User

-> Oracle provided two pre-defined PROCEDURES

a. RAISE

b. RAISE_APPLICATION_ERROR

a. RAISE :
-----------

-> It is one of the pre-defined procedures and used throws user defined
exception name into exception block

syn:-

RAISE <user-defined_exception-name>;

b. RAISE_APPLICATION_ERROR :
----------------------------

-> This procedure is used to displays ERROR messages with ERROR code

-> It accepts two arguments


syntax:
-------

RAISE_APPLICATION_ERROR( user_defined_error_code,
user_defined_error_message );

-> Oracle provided user_defined_error_codes from -20001 to -20999

example :
---------

-- write a pl/sql block to restrict DML commands on Every WEEK-ENDs

Declare
holiday Exception;
Begin
if to_char(sysdate,'dy') in ( 'sat','sun') then
RAISE holiday;
else
dbms_output.put_line('DML Transactions are Allows.');
end if;
Exception
when holiday then
raise_application_error( -20001, 'Week-Ends Transactions are not
allowed.');
End;
/

Declare
*
ERROR at line 1:
ORA-20001: Week-Ends Transactions are not allowed.
ORA-06512: at line 11

-- Write a user-defined exception block to raise error if any employee is


not getting COMMISSION

validations :
-------------

-> Commission is applicable for only SALESMAN jobs

Declare
v_empno emp.empno%type := &Empno;
v_job emp.job%type;
ABC Exception;
Begin
select job into v_job from emp where empno = v_empno;
if V_Job != 'SALESMAN' then
RAISE ABC;
else
dbms_output.put_line('Employee is Eliible for COMMISSION.');
end if;
Exception
when ABC THEN
RAISE_APPLICATION_ERROR(-20001, 'Employee is Not Eligible for
Commission.');
End;
/

Enter value for empno: 7788


Declare
*
ERROR at line 1:
ORA-20001: Employee is Not Eligible for Commission.
ORA-06512: at line 14

SQL> /
Enter value for empno: 7521
Employee is Eliible for COMMISSION.

PL/SQL procedure successfully completed.

III. NON PRE-DEFINED EXCEPTIONS :


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

-> These exceptions are used to handle, Constraint voilated Error


Messages

-> In this exceptions...

i. Exception Name is Defined by USER

ii. Activated by ORACLE

iii. Solution is Provided by USER

PRAGMA EXCEPTION_INIT :
-----------------------

-> It is one of the pre-defined procedure

-> this procedure is USER_DEFINED Exception Name is Associated with


Oracle Error Code

syn:-

PRAGMA EXCEPTION_INIT( User_defined_exception_name, Oracle_Error_code );

example :
---------

-- write pl/sql block to handel UNIQUE constraint error message

Declare
Duplicates_Found Exception;
Pragma Exception_Init( Duplicates_Found, -00001 );
Begin
Insert Into Dept Values ( &deptno, '&dname', '&loc' );
dbms_output.put_line('record inserted.');
Exception
when duplicates_found then
raise_application_error(-20001, 'Given Dept. No. Already Exists....');
End;
/
Enter value for deptno: 50
Enter value for dname: MATHS
Enter value for loc: HYD
record inserted.

PL/SQL procedure successfully completed.

SQL> Declare
2 Duplicates_Found Exception;
3 Pragma Exception_Init( Duplicates_Found, -00001 );
4 Begin
5 Insert Into Dept Values ( &deptno, '&dname', '&loc' );
6 dbms_output.put_line('record inserted.');
7 Exception
8 when duplicates_found then
9 raise_application_error(-20001, 'Given Dept. No. Already
Exists....');
10 End;
11 /
Enter value for deptno: 50
Enter value for dname: ENG
Enter value for loc: SEC
Declare
*
ERROR at line 1:
ORA-20001: Given Dept. No. Already Exists....
ORA-06512: at line 9

Example :
=========

-- to handle, NOT NULL Constraint Error Message

Declare
Duplicates_Found Exception;
Pragma Exception_Init( Duplicates_Found, -00001 );
Nulls_Found Exception;
Pragma Exception_Init( Nulls_Found, -01400 );
Begin
Insert Into Dept Values ( &deptno, '&dname', '&loc' );
dbms_output.put_line('record inserted.');
Exception
when duplicates_found then
raise_application_error(-20001, 'Given Dept. No. Already Exists....');
when NULLS_FOUND then
raise_application_error(-20002, 'Deptno Column Value is
Mandatory....');
End;
/

Enter value for deptno: NULL


Enter value for dname: ENG
Enter value for loc: SEC
Declare
*
ERROR at line 1:
ORA-20002: Deptno Column Value is Mandatory....
ORA-06512: at line 13
OTHERS :
--------

-> It is one of the PRE-DEFINED Exception Name

-> In Exception Block, if there is no matching exceptions names to


handel then
by default OTHERS is executed. so, OTHERS exception name is also
called as
DEFAULT Exception

-> PL/SQL provided two pre-defined functions

i. SQLCODE :- It returns currently raising error code

ii. SQLERRM :- It returns currently raising error message

Example :
---------

Declare
v_ename emp.ename%type;
Begin
select ename into v_ename from emp;
dbms_output.put_line( v_ename );
exception
when no_data_found then
raise_application_error(-20001, 'Given Employee Record Not
Exists,....');
when OTHERS then
dbms_output.put_line( 'Raising Error Code : ' || SQLCODE);
dbms_output.put_line( 'Raising Error Message : ' || SQLERRM);
raise_application_error(-20002, 'Default Exception is Raised.');
end;
/

Raising Error Code : -1422


Raising Error Message : ORA-01422: exact fetch returns more than
requested number of rows
Declare
*
ERROR at line 1:
ORA-20002: Default Exception is Raised.
ORA-06512: at line 12

ADVANCED PL/SQL Concepts :


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

ADVANCED PL/SQL Concepts :


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

Named Block Programs :


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

-> A set of pl/sql programs stored in DB permanently is called as Named


Blocks
-> Examples of Named Blocks are....

ex: Stored Procedures, User Defined Functions, Triggers &


Packages

SUB-PROGRAMS :
--------------

-> Sub-programs are self-contained Block Programs

-> Sub-Programs are created by using 'CREATE' command

-> Sub-Programs are stored in DB permanently

-> Sub-Programs main advantages are...

i. Modularity :- A Huge Program is devided into sub-programs

Adv. :
------

a. Easy to Understand

b. Easy to debug the errors

ii. Re-usability :- Once sub-program created then it is stored DB


permanently so, that is re-usability

iii. It Improves the Performance :- Sub-Programs are stored in


Compiled format. So, once sub-program is created
then we can execute the program
no need to compile every time

-> All Created sub-programs Bodies are stored in USER_SOURCE table(


pre-defined table )

-> All Created sub-program Names are stored in USER_OBJECTS table (


pre-defined table )

-> Sub-Programs are two types

i. Stored Procedure

ii. User-Defined Functions

i. Stored Procedure :
---------------------

-> A Set of PL/SQL statements stored in db permanently and performs a


task

-> Stored procedures are stored in DB permanently

-> Stored Procedures main advantages are...


i. modularity

ii. re-usability

iii. It improves the performance

-> All created stored procedure Bodies are stored in USER_SOURCE table &
Procedure Names are stored in USER_OBJECTS table

Syn:-

Create or Replace Procedure <Procedure_Name>


[( Arg1 Mode Datatype, Arg2 Mode Datatype,..)]
is
[<variable_declaration>;]
Begin
<exec-statements>;
[Exception
<exec-statements>;]
End [ <procedure_name>] ;
/

Example :
---------

-- Write a stored procedure to display WELCOME message

Create or Replace Procedure my_proc


is
Begin
dbms_output.put_line( 'Welcome to Stored Procedures....');
End my_proc;
/

How to execute the procedure :


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

on SQL prompt :
---------------

syn:- EXEC <Procedure_Name>;

Example :
---------

SQL> Exec My_proc;


Welcome to Stored Procedures....

PL/SQL procedure successfully completed.

Using PL/SQL Block :


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

syn:-

Begin
<Procedure_Name>;
End;
/
example :
---------

SQL> Begin
my_proc;
End;
/

Welcome to Stored Procedures....

PL/SQL procedure successfully completed.

** to see the created procedure body

SQL> select text from user_source where name='MY_PROC';

TEXT
----------------------------------------------------------------------
Procedure my_proc
is
Begin
dbms_output.put_line( 'Welcome to Stored Procedures....');
End my_proc;

-- to see the list of created procedure names

SQL> select object_name from user_objects where object_type='PROCEDURE';

OBJECT_NAME
-------------------------------------------------------------------------
----------------
MY_PROC

-- write a stored procedure to find sum of two numbers

Create or replace procedure add_proc


is
x Number(5) := 100;
y Number(5) := 200;
Begin
dbms_output.put_line( 'Sum of Two Numbers = ' || (x+y))
End add_proc;
/

Warning: Procedure created with compilation errors.

SQL> show errors


Errors for PROCEDURE ADD_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
7/1 PLS-00103: Encountered the symbol "END" when expecting one of
the
following:
:= . ( % ;
The symbol ";" was substituted for "END" to continue.

Create or replace procedure add_proc


is
x Number(5) := 100;
y Number(5) := 200;
Begin
dbms_output.put_line( 'Sum of Two Numbers = ' || (x+y));
End add_proc;
/

SQL> exec add_proc;


Sum of Two Numbers = 300

PL/SQL procedure successfully completed.

SQL> exec add_proc;


Sum of Two Numbers = 300

PL/SQL procedure successfully completed.

** to take values at run-time

Create or replace procedure add_proc


is
x Number(5) := &x;
y Number(5) := &y;
Begin
dbms_output.put_line( 'Sum of Two Numbers = ' || (x+y));
End add_proc;
/

Enter value for x: 300


Enter value for y: 600

Procedure created.

SQL> exec add_proc;


Sum of Two Numbers = 900

PL/SQL procedure successfully completed.

SQL> exec add_proc;


Sum of Two Numbers = 900

PL/SQL procedure successfully completed.

note :- Above program returns same output every time because procedures
are compiled only one time. To take values at run-time then
to use Procedures with Parameters

Procedures with Parameters :


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

-> While calling the Procedures to pass parameter values is called as


Procedure wiht Parameters

-> Maximum 32 parameters are allowed

-> Procedures are supports three types of Parameter Modes like,... IN,
OUT, IN OUT
example :
---------

-- write a stored prcedure to find sum of two given nubers

Create or replace procedure add_proc


( x number, y number )
is
Begin
dbms_output.put_line( 'Sum of two Numbers = ' || ( x + y ) ) ;
End add_proc;
/

SQL> Exec add_proc( 100, 500 );


Sum of two Numbers = 600

PL/SQL procedure successfully completed.

SQL> Exec add_proc( 600, 900 );


Sum of two Numbers = 1500

PL/SQL procedure successfully completed.

Procedures with Parameters :


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

-> While calling the Procedures to pass parameter values is called as


Procedure wiht Parameters

-> Maximum 32 parameters are allowed

-> Procedures are supports three types of Parameter Modes like,... IN,
OUT, IN OUT

example :
---------

-- write a stored prcedure to find sum of two given nubers

Create or replace procedure add_proc


( x number, y number )
is
Begin
dbms_output.put_line( 'Sum of two Numbers = ' || ( x + y ) ) ;
End add_proc;
/

SQL> Exec add_proc( 100, 500 );


Sum of two Numbers = 600

PL/SQL procedure successfully completed.

SQL> Exec add_proc( 600, 900 );


Sum of two Numbers = 1500
PL/SQL procedure successfully completed.

-- write a stored procedure to input employee no. and display


corresponding employee record

Create or replace procedure EMP_REC


( p_Empno Emp.empno%type )
is
e emp%rowtype;
Begin
select * into e from emp where empno = p_Empno;
dbms_output.put_line( e.empno ||' '||e.ename||' '||e.job||' '||e.mgr||'
'||e.hiredate||' '||e.sal||' '||e.deptno );
Exception
when No_data_found then
raise_application_error(-20001, 'Employ Record Not Found.');
End Emp_Rec;
/

Calling Procedure :
-------------------

SQL> EXEC EMP_REC( 7788 );


7788 SCOTT ANALYST 7566 09-DEC-82 3100 20

PL/SQL procedure successfully completed.

SQL> EXEC EMP_REC( 7839 );


7839 KING PRESIDENT 17-NOV-81 5000 10

PL/SQL procedure successfully completed.

SQL> EXEC EMP_REC( 7000 );


BEGIN EMP_REC( 7000 ); END;

*
ERROR at line 1:
ORA-20001: Employ Record Not Found.
ORA-06512: at "ORA8PM.EMP_REC", line 10
ORA-06512: at line 1

Procedure using INSERT command :


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

-- write a stored procedure to insert data into dept. table

Create or replace procedure dept_ins_proc


( P_deptno dept.deptno%type,
P_Dname dept.dname%type,
P_Loc dept.loc%type
)
is
Begin
Insert Into Dept Values ( p_deptno, p_dname, p_loc );
dbms_output.put_line( 'Record Inserted');
End dept_ins_proc;
/
SQL> Exec dept_ins_Proc( 60, 'Eng', 'Sec');
Record Inserted

PL/SQL procedure successfully completed.

SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD
60 Eng Sec

6 rows selected.

Stored procedure using UPDATE command :


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

-- Stored procedure to increment employee salary based on the given pct

Create or replace procedure EMP_UPD_PROC


( p_empno emp.empno%type, -- 7839
p_pct Number -- 20
)
is
Begin
Update emp set sal = sal + sal * p_pct/100 where empno = p_empno;
if sql%found then
dbms_output.put_line('Salary Incremented Successfully.');
else
dbms_output.put_line('Employ Record Not Found');
end if;
End Emp_Upd_Proc;
/

SQL> Exec Emp_Upd_Proc( 7839, 20 );


Salary Incremented Successfully.

PL/SQL procedure successfully completed.

SQL> Exec Emp_Upd_Proc( 9000, 10 );


Employ Record Not Found

PL/SQL procedure successfully completed.

-- Stored Procedure using DELETE command

Ex:-

-- write a stored procedure To Delete a Record

Create or replace procedure EMP_DEL_REC


( P_EMPNO EMP.EMPNO%TYPE )
IS
Begin
Delete from Emp where empno=p_Empno;
if sql%found then
dbms_output.put_line('Record Deleted Successfully.');
else
dbms_output.put_line('Employ Record Not Found.');
end if;
End EMP_DEL_REC;
/

SQL> Exec emp_del_rec( 7788 );


Record Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> Exec emp_del_rec( 7788 );


Employ Record Not Found.

PL/SQL procedure successfully completed.

PROCEDURES with PARAMETER MODES :


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

-> Parameter mode specifies type of the PARAMETER

-> Pl/sql supports three types of Parameter Modes

i. IN

ii. OUT

iii. IN OUT

i. IN :
--------

-> This parameter mode is taking input into PROCEDURE

-> By default All Parameters are taking IN parameters

-> On IN parameter mode variables Assignment targets ( = ) are not


supported

ex:-

-- write a stored prcedure to find sum of two given nubers

Create or replace procedure add_proc


( x in number, y in number )
is
Begin
dbms_output.put_line( 'Sum of two Numbers = ' || ( x + y ) ) ;
End add_proc;
/

SQL> Exec add_proc( 100, 500 );


Sum of two Numbers = 600

On IN parameter mode variables Assignment targets ( := ) are not


supported :
*************************************************************************
***

-- write a stored prcedure to find sum of two given nubers

Create or replace procedure add_proc


( x in number, y in number )
is
Begin
x := 800;
dbms_output.put_line( 'Sum of two Numbers = ' || ( x + y ) ) ;
End add_proc;
/

Warning: Procedure created with compilation errors.

SQL> show errors


Errors for PROCEDURE ADD_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
5/3 PL/SQL: Statement ignored
5/3 PLS-00363: expression 'X' cannot be used as an assignment target

ii. OUT :
---------

-> This Parameter mode is used to RETURN output through Stored


Procedure

-> Generally Procedures MAY/MAY NOT return values. But, by using OUT
parameter mode it returns output

-> On OUT parameter mode variables assignment targets are supported

Example :
---------

-- Stored Procedure for to find sum of two given number and return
output

Create or replace procedure ADD_PROC


( X In Number, Y In Number, Z Out Number )
is
Begin
Z := X + Y;
End Add_Proc;
/

Procedure created.

SQL> Variable RES NUMBER;

SQL> Exec Add_Proc ( 200, 700 , :res );

PL/SQL procedure successfully completed.

SQL> Print :RES;


RES
------
900

NOTE: To declare variables on SQL PROMT that type variables are called as
BIND / GLOBAL VARIABLES

These variables scope is Session valid.

SQL variables ( res ) are represented with preceeding ':' OPERATOR

PROCEDURES with PARAMETER MODES :


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

-> Parameter mode specifies type of the PARAMETER

-> Pl/sql supports three types of Parameter Modes

i. IN

ii. OUT

iii. IN OUT

i. IN :
--------

-> This parameter mode is taking input into PROCEDURE

-> By default All Parameters are taking IN parameters

-> On IN parameter mode variables Assignment targets ( = ) are not


supported

ex:-

-- write a stored prcedure to find sum of two given nubers

Create or replace procedure add_proc


( x in number, y in number )
is
Begin
dbms_output.put_line( 'Sum of two Numbers = ' || ( x + y ) ) ;
End add_proc;
/

SQL> Exec add_proc( 100, 500 );


Sum of two Numbers = 600

On IN parameter mode variables Assignment targets ( := ) are not


supported :
*************************************************************************
***

-- write a stored prcedure to find sum of two given nubers


Create or replace procedure add_proc
( x in number, y in number )
is
Begin
x := 800;
dbms_output.put_line( 'Sum of two Numbers = ' || ( x + y ) ) ;
End add_proc;
/

Warning: Procedure created with compilation errors.

SQL> show errors


Errors for PROCEDURE ADD_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
5/3 PL/SQL: Statement ignored
5/3 PLS-00363: expression 'X' cannot be used as an assignment target

ii. OUT :
---------

-> This Parameter mode is used to RETURN output through Stored


Procedure

-> Generally Procedures MAY/MAY NOT return values. But, by using OUT
parameter mode it returns output

-> On OUT parameter mode variables assignment targets are supported

Example :
---------

-- Stored Procedure for to find sum of two given number and return
output

Create or replace procedure ADD_PROC


( X In Number, Y In Number, Z Out Number )
is
Begin
Z := X + Y;
End Add_Proc;
/

Procedure created.

SQL> Variable RES NUMBER;

SQL> Exec Add_Proc ( 200, 700 , :res );

PL/SQL procedure successfully completed.

SQL> Print :RES;

RES
------
900
NOTE: To declare variables on SQL PROMT that type variables are called as
BIND / GLOBAL VARIABLES

These variables scope is Session valid.

SQL variables ( res ) are represented with preceeding ':' OPERATOR

Ex2:-

-- write a stored procedure to input EMPLOYEE NO and return


corresponding employee JOB

Create or replace procedure emp_job( p_empno In emp.empno%type, p_job Out


emp.job%type )
is
Begin
select job into p_job from emp where empno = p_empno;
End emp_job;
/

Calling Procedure on SQL Prompt :


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

SQL> VARIABLE V_JOB VARCHAR2(30);


SQL> EXEC EMP_JOB( 7839, :V_JOB);

PL/SQL procedure successfully completed.

SQL> PRINT :V_JOB;

V_JOB
-------------------------------------------------------------------------
-------------------
PRESIDENT

calling procedure using PL/SQL Block :


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

declare
v_job emp.job%type;
Begin
Emp_Job( 7839, v_job ); -- calling procedure
dbms_output.put_line( 'Given Employee Job is ' || v_job );
End;
/

Given Employee Job is PRESIDENT

PL/SQL procedure successfully completed.

declare
v_job emp.job%type;
Begin
Emp_Job( &Empno, v_job ); -- calling procedure
dbms_output.put_line( 'Given Employee Job is ' || v_job );
End;
/
Enter value for empno: 7521
Given Employee Job is SALESMAN

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7902
Given Employee Job is ANALYST

PL/SQL procedure successfully completed.

-- Write a stored procedure to input employee no and return corresponding


employee name, job, salary & deptno

Create or replace procedure emp_find( p_empno in emp.empno%type,


p_ename out emp.ename%type,
p_job out emp.job%type,
p_sal out emp.sal%type,
p_deptno out emp.deptno%type
)
is
Begin
select ename, job, sal, deptno Into
p_ename, p_job, p_sal, p_deptno from emp
where empno = p_empno;
End emp_find;
/

How to call this program in BACK-END DB :


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

Declare
v_empno emp.empno%type := &empno;
v_ename emp.ename%type;
v_job emp.job%type;
v_sal emp.sal%type;
v_deptno emp.deptno%type;
Begin
Emp_Find( v_empno, v_ename, v_job, v_sal, v_deptno ); -- calling
procedure
dbms_output.put_line( 'Emp No : '||v_empno);
dbms_output.put_line( 'Emp Name : '||v_ename);
dbms_output.put_line( 'Emp Job : '||v_job);
dbms_output.put_line( 'Emp Salary : '||v_sal );
dbms_output.put_line( 'Emp Deptno : '||v_deptno);
End;
/

Enter value for empno: 7839


Emp No : 7839
Emp Name : KING
Emp Job : PRESIDENT
Emp Salary : 6000
Emp Deptno : 10

PL/SQL procedure successfully completed.


SQL> /
Enter value for empno: 7521
Emp No : 7521
Emp Name : WARD
Emp Job : SALESMAN
Emp Salary : 1250
Emp Deptno : 30

PL/SQL procedure successfully completed.

-- Write a stored Procedure to create a new user account

Table Creation :
----------------

Create table user_details( user_id varchar2(10), User_name Varchar2(20),


password varchar2(20), Role Varchar2(20) );

Validations :
-------------

-> User id should be generate automatically

ex:- U1, U2,....

-> Password should be contain min. 6 characters

-> Enter Password and Confirm password should be same

-> Role should be accepts ADMIN, EMPLOY or CUSTOMER

Sequence for to generate USER IDs :


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

Create Sequence user_id_Seq


start with 1
Increment by 1;

Stored Procedure :
------------------

Create or replace procedure user_reg_proc ( p_user_name In


User_Details.user_name%type,
p_password In User_Details.Password%type,
p_cnf_password In
User_Details.Password%type,
p_Role In user_details.role%type,
p_status Out Varchar2
)
is
Begin
If Length( p_password ) < 6 then
p_Status := 'Min. Length of Password is 6 characters.';
Elsif p_password != p_cnf_password then
p_Status := 'Enter and Confirm Passwords should be Sampe.';
Elsif p_role NOT IN ( 'ADMIN', 'EMPLOY', 'CUSTOMER' ) then
p_Status := 'Invalid Role!!!!';
Else
Insert Into User_Details Values( 'U'||(user_id_seq.nextval),
p_user_name, p_password, p_Role );
p_Status := 'User Created Successfully.';
End if;
End User_Reg_Proc;
/

Write a stored Procedure to create a new user account

Table Creation :
----------------

Create table user_details( user_id varchar2(10), User_name Varchar2(20),


password varchar2(20), Role Varchar2(20) );

Validations :
-------------

-> User id should be generate automatically

ex:- U1, U2,....

-> Password should be contain min. 6 characters

-> Enter Password and Confirm password should be same

-> Role should be accepts ADMIN, EMPLOY or CUSTOMER

Sequence for to generate USER IDs :


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

Create Sequence user_id_Seq


start with 1
Increment by 1;

Stored Procedure :
------------------

Create or replace procedure user_reg_proc ( p_user_name In


User_Details.user_name%type,
p_password In User_Details.Password%type,
p_cnf_password In
User_Details.Password%type,
p_Role In user_details.role%type,
p_status Out Varchar2
)
is
Begin
If Length( p_password ) < 6 then
p_Status := 'Min. Length of Password is 6 characters.';
Elsif p_password != p_cnf_password then
p_Status := 'Enter and Confirm Passwords should be Sampe.';
Elsif upper(p_role) NOT IN ( 'ADMIN', 'EMPLOY', 'CUSTOMER' ) then
p_Status := 'Invalid Role!!!!';
Else
Insert Into User_Details Values( 'U'||(user_id_seq.nextval),
p_user_name, p_password, p_Role );
p_Status := 'User Created Successfully.';
commit;
End if;
End User_Reg_Proc;
/

CALLING PROCEDURE :
-------------------

declare
status varchar2(100);
begin
user_reg_proc( &user_name, &password, &cnf_password, &Role, status ); -
- calling procedure
dbms_output.put_line( Status );
End;
/

Enter value for user_name: 'king'


Enter value for password: 'king123'
Enter value for cnf_password: 'king123'
Enter value for role: 'admin'
User Created Successfully.

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'scott'
Enter value for password: 'scot123'
Enter value for cnf_password: 'scott123'
Enter value for role: 'employ'
Enter and Confirm Passwords should be Sampe.

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'scott'
Enter value for password: 'scott123'
Enter value for cnf_password: 'scott123'
Enter value for role: 'employ'
User Created Successfully.

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'smith'
Enter value for password: 'smith'
Enter value for cnf_password: 'smith'
Enter value for role: 'admin
ERROR:
ORA-01756: quoted string not properly terminated

SQL> /
Enter value for user_name: 'smith'
Enter value for password: 'smith'
Enter value for cnf_password: 'smith'
Enter value for role: 'admin'
Min. Length of Password is 6 characters.
PL/SQL procedure successfully completed.

SQL>
SQL>
SQL> /
Enter value for user_name: 'smith'
Enter value for password: 'smith123'
Enter value for cnf_password: 'smith123'
Enter value for role: 'guest'
Invalid Role!!!!

PL/SQL procedure successfully completed.

SQL> select * from user_details;

USER_ID USER_NAME PASSWORD ROLE


---------- -------------------- -------------------- --------------------
U1 king king123 admin
U2 scott scott123 employ

-- write a stored procedure to input Username, password and return the


status

Create or replace procedure Login_Proc


( p_user_Name In User_details.user_name%type, -- king
p_password In user_details.password%type, -- king123
p_status OUT Varchar2
)
is

v_cnt Number;
Begin
select count(*) Into v_cnt from User_Details where user_name =
p_user_name
and
password = p_password;
if v_cnt > 0 then
p_status := 'Login Successfully ';
else
p_status := 'Invalid UserName/Password';
end if;
End Login_Proc;
/

calling program :
-----------------

declare
status varchar2(100);
Begin
login_proc( &user_name, &password , status ); -- calling procedure
dbms_output.put_line( status );
End;
/

Enter value for user_name: 'king'


Enter value for password: 'king123'
Login Successfully

PL/SQL procedure successfully completed.

SQL>
SQL> /
Enter value for user_name: 'scott'
Enter value for password: 'scott123'
Login Successfully

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'king'
Enter value for password: 'king'
Invalid UserName/Password

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'smith'
Enter value for password: 'smith123'
Invalid UserName/Password

PL/SQL procedure successfully completed.

PROCEDURES with DEFAULT Arguments :


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

-> While calling the procedures if we are not passing any value to
parameter by default
procedures takes specified DEFAULT value

ex:-

-- stored procedure for to insert data into DEPT table

Create or replace procedure dept_proc


( p_deptno dept.deptno%type,
p_dname dept.dname%type default 'Unknown',
p_loc dept.loc%type default 'Unknown'
)
is
Begin
Insert Into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line('record inserted.');
End dept_Proc;
/

PROCEDURES with DEFAULT Arguments :


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

-> While calling the procedures if we are not passing any value to
parameter by default
procedures takes specified DEFAULT value

ex:-
-- stored procedure for to insert data into DEPT table

Create or replace procedure dept_proc


( p_deptno dept.deptno%type,
p_dname dept.dname%type default 'Unknown',
p_loc dept.loc%type default 'Unknown'
)
is
Begin
Insert Into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line('record inserted.');
End dept_Proc;
/
SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

SQL> Exec Dept_Proc( 50, 'MATHS' );


record inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown

SQL> Exec Dept_Proc( 60, 'HYD' );


record inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown
60 HYD Unknown

6 rows selected.

Note: in the 2nd Execution Dept. Name is taken as 'HYD' & loc taken as
'Unknown'. To overcome this problem Procedures are supports
NOTATIONS concept.
NOTATIONS :
-----------

-> Procedures are supports three types of NOTATIONS

i. Positional Notation

ii. Named Notation

iii. Mixed Notation

i. Positional Notation :
------------------------

-> While calling the procedures to pass parameter values according


corresponding Parameter Positions is called as Positional
Notation.

-> By default all procedures are executing in this method

ex:- Exec Dept_Proc( 50, 'MATHS', 'HYD' );

ii. Named Notations :


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

-> While calling the procedure to pass parameter values by using


FORMAL ARGUMENT Names is called as Named Notations.

ex:-

SQL> Exec Dept_Proc( P_LOC => 'HYD', P_DEPTNO=> 70, P_DNAME => 'ENG' );
record inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown
60 HYD Unknown
70 ENG HYD

7 rows selected.

III. MIXED NOTATIONS :


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

-> Both Positional and Named Notations are called as MIXED NOTATIONS

ex:-

SQL> EXEC DEPT_PROC( 80, P_LOC => 'SEC' );


record inserted.
PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown
60 HYD Unknown
70 ENG HYD
80 Unknown SEC

8 rows selected.

** To see the created procedure bodies

SQL> select text from user_source where name='DEPT_PROC';

TEXT
-------------------------------------------------------------------------
---------------------------
procedure dept_proc
( p_deptno dept.deptno%type,
p_dname dept.dname%type default 'Unknown',
p_loc dept.loc%type default 'Unknown'
)
is
Begin
Insert Into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line('record inserted.');
End dept_Proc;

10 rows selected.

** To see the procedure names

SQL> select object_name from user_objects where object_type='PROCEDURE';

OBJECT_NAME
-------------------------------------------------------------------------
-----------------
DEPT_PROC
LOGIN_PROC
EMP_DEL_REC
EMP_UPD_PROC
DEPT_INS_PROC
EMP_REC
USER_REG_PROC
EMP_FIND
EMP_JOB
ADD_PROC
MY_PROC

11 rows selected.

** Dropping Procedures
syn:- Drop Procedure <Procedure_Name>;

ex:- Drop Procedure my_Proc;

II. USER-DEFINED FUNCTIONS :


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

-> According to client requirement developer write with his own logic
and own function name is called as user-defined functions.

-> User-defined functions are also return values by using RETURN


statement & User-defined functions should be return a value

-> User-defined functions are supports Parameters and Parameter Modes

-> User-defined functions main advantages are...

i. modularity

ii. re-usability

iii. it improves the performance


-> All created
user-defined function names are stored in USER_OBJECTS table ( pre-
defined table )

-> All Created User-defined function Bodies are stored in USER_SOURCE


Table ( pre-defined table )

syntax :-

Create or replace FUNCTION <function_name>


[( arg1 mode datatype, arg2 mode datatype..)]
RETURN <data-type>
is
[ <variable-declaration>;]
Begin
<exec-statements>;
Return( value );
[Exception
<exec-statements>;
Return( value );]
End [<function_name>];
/

Examples :-

-- write a user-defined function to find Simple Interest

Interest = ( PTR )/100;

Create or replace Function Simple_Int( P Number, T Number, R Number )


Return NUMBER
is
Interest Number;
Begin
Interest := (P * T * R) /100;
return( Interest);
End Simple_Int;
/

Calling Function :
------------------

on SQL Prompt :
---------------

method 1 :
----------

SQL> Select Simple_Int( 1000, 2, 10 ) from dual;

SIMPLE_INT(1000,2,10)
---------------------
200

method 2 :
----------

SQL> variable interest number;

SQL> EXEC :Interest := SIMPLE_INT( 1000, 2, 10 );

PL/SQL procedure successfully completed.

SQL> PRINT :INTERest;

INTEREST
----------
200

using PL/SQL Block :


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

method 3 :
----------

declare
interest number;
begin
select simple_int(1000,2,10) into Interest from dual;
dbms_output.put_line( 'Simple Interest = '||Interest );
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

method 4 :
----------

declare
interest number;
begin
interest := simple_int(1000,2,10);
dbms_output.put_line( 'Simple Interest = '||Interest );
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

method 5 :
----------

Begin
dbms_output.put_line( 'Simple Interest = '||Simple_Int(1000,2,10) );
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

Example 2:
----------

-- write a user-defined function to input employee no. and return


corresponding employee NETSALARY

Create or replace function emp_netsal( p_empno emp.empno%type)


Return Varchar2
is
netsal number;
begin
select sal + nvl(comm,0) into netsal from emp
where empno=p_empno;
return( p_empno||' Employee Net Salary Rs.'||netsal);
Exception
when no_data_found then
Return( 'Employ Record Not Found.');
End emp_netsal;
/

SQL> select emp_netsal( 7839) from dual;

EMP_NETSAL(7839)
-----------------------------------------
7839 Employee Net Salary Rs.6000

SQL> select emp_netsal( 7521) from dual;

EMP_NETSAL(7521)
-----------------------------------------
7521 Employee Net Salary Rs.1750

SQL> COLUMN NETSAL FORMAT A40;


SQL> select EMPNO, ENAME, SAL, COMM, EMP_NETSAL( EMPNO ) AS NETSAL FROM
EMP;

EMPNO ENAME SAL COMM NETSAL


---------- ---------- ---------- ---------- -----------------------------
-----------
7369 SMITH 900 7369 Employee Net Salary
Rs.900
7499 ALLEN 1600 300 7499 Employee Net Salary
Rs.1900
7521 WARD 1250 500 7521 Employee Net Salary
Rs.1750
7566 JONES 3075 7566 Employee Net Salary
Rs.3075
7654 MARTIN 1250 1400 7654 Employee Net Salary
Rs.2650
7698 BLAKE 2850 7698 Employee Net Salary
Rs.2850
7782 CLARK 2450 7782 Employee Net Salary
Rs.2450
7839 KING 6000 7839 Employee Net Salary
Rs.6000
7844 TURNER 1500 0 7844 Employee Net Salary
Rs.1500
7876 ADAMS 1200 7876 Employee Net Salary
Rs.1200
7900 JAMES 950 7900 Employee Net Salary
Rs.950
7902 FORD 3100 7902 Employee Net Salary
Rs.3100
7934 MILLER 1300 7934 Employee Net Salary
Rs.1300

13 rows selected.

Example 3 :
-----------

Function Return type is BOOLEAN :


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

-- write a user defined function to find given employee record found or


not

Create or replace function emp_find ( p_empno emp.empno%type )


return BOOLEAN
is
cnt number;
Begin
select count(*) into cnt from emp where empno = p_empno;
if cnt>0 then
return( True );
else
return( False );
End if;
End emp_find;
/

SQL> select emp_find( 7839 ) from dual;


select emp_find( 7839 ) from dual
*
ERROR at line 1:
ORA-06552: PL/SQL: Statement ignored
ORA-06553: PLS-382: expression is of wrong type
note: above function returns OUTPUT to SQL prompt, but sql not supported
BOOLEAN datatype, we must execute above function
using PL/SQL block.

Begin
if emp_find( &empno ) = True then
dbms_output.put_line( 'Employ Record Found.');
else
dbms_output.put_line( 'Employ Record Not Found.');
end if;
End;
/

Enter value for empno: 7521


Employ Record Found.

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 9000
Employ Record Not Found.

PL/SQL procedure successfully completed.

-- write a pl/sql block to declare each employee increment based on


following conditions.

if employee experience >=10 then 50% increment

if employee experience <10 years then 30% increment

and increment details should be stored in EMPLOY_INCR table

Table creation :
----------------

Create Table Employ_Incr( empno number(4), incr_date date, Expe


Number(5,2), incr_amt Number(8,2));

Fuction for to return experience :


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

Create or replace function emp_exp( p_empno emp.empno%type )


return Number
is
v_exp number;
Begin
select round( months_between( sysdate, hiredate )/12, 1 ) into v_exp
from emp
where empno = p_empno;
return ( v_exp );
End emp_exp;
/

-- write a pl/sql block to declare each employee increment based on


following conditions.

if employee experience >=10 then 50% increment


if employee experience <10 years then 30% increment

and increment details should be stored in EMPLOY_INCR table

Table creation :
----------------

Create Table Employ_Incr( empno number(4), incr_date date, Expe


Number(5,2), incr_amt Number(8,2));

Fuction for to return experience :


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

Create or replace function emp_exp( p_empno emp.empno%type )


return Number
is
v_exp number;
Begin
select round( months_between( sysdate, hiredate )/12, 1 ) into v_exp
from emp
where empno = p_empno;
return ( v_exp );
End emp_exp;
/

Procedure to increment employee salaries :


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

Create or replace procedure emp_incr_Proc


is
Cursor e_cur is select empno, sal from emp;
v_empno emp.empno%type;
v_sal emp.sal%type;
v_incr_sal Number;
Begin
open e_cur;
loop
fetch e_cur into v_empno, v_sal; -- 7369, 900
exit when e_cur%notfound;
if emp_exp( v_empno ) >=10 then
v_incr_sal := v_sal * 0.5;
else
v_incr_sal := v_sal * 0.3;
end if;
Insert into Employ_Incr values ( v_empno, sysdate, emp_exp(v_empno),
v_incr_sal );
Update emp set sal = sal + v_incr_sal where empno = v_empno;
end loop;
close e_cur;
dbms_output.put_line( 'Employ Salary Incremented Successfully....');
End emp_incr_Proc;
/

SQL> exec emp_incr_proc;


Employ Salary Incremented Successfully....

PL/SQL procedure successfully completed.


SQL> select * from employ_incr;

EMPNO INCR_DATE EXPE INCR_AMT


---------- --------- ---------- ----------
7369 17-OCT-23 42.8 450
7499 17-OCT-23 42.7 800
7521 17-OCT-23 42.7 625
7566 17-OCT-23 42.5 1537.5
7654 17-OCT-23 42.1 625
7698 17-OCT-23 42.5 1425
7782 17-OCT-23 42.4 1225
7839 17-OCT-23 41.9 3000
7844 17-OCT-23 42.1 750
7876 17-OCT-23 40.8 600
7900 17-OCT-23 41.9 475
7902 17-OCT-23 41.9 1550
7934 17-OCT-23 41.7 650

13 rows selected.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 1350
20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400
300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875
500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5
20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875
1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275
30
7782 CLARK MANAGER 7839 09-JUN-81 3675
10
7839 KING PRESIDENT 17-NOV-81 9000
10
7844 TURNER SALESMAN 7698 08-SEP-81 2250
0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800
20
7900 JAMES CLERK 7698 03-DEC-81 1425
30
7902 FORD ANALYST 7566 03-DEC-81 4650
20
7934 MILLER CLERK 7782 23-JAN-82 1950
10

13 rows selected.

-- write a user defined function to find first name from given name

Create or replace function fname( Name varchar2 ) -- rama krishna raju


return Varchar2
is
fname varchar2(100);
Begin
fname := Substr( Name, 1, instr(Name, ' ',1,1 )-1 );
return( fname );
End fname;
/

SQL> select fname( 'RAMA KRISHNA RAJU' ) FROM DUAL;

FNAME('RAMAKRISHNARAJU')
---------------------------------------------------------------------
RAMA

SQL> select fname( 'KRISHNA RAJU' ) FROM DUAL;

FNAME('KRISHNARAJU')
---------------------------------------------------------------------
KRISHNA

-- write a user defined function return LAST NAME

-- write a user defined function return MIDDLE NAME

** to see the created function names

SQL> select object_name from user_objects where OBJECT_TYPE='FUNCTION';

OBJECT_NAME
-------------------------------------------------------------------------
---
EMP_FIND
EMP_NETSAL
SIMPLE_INT
EMP_EXP
FNAME

** To see the particular function body

SQL> select text from user_source where name='EMP_INCR_PROC';

TEXT
-------------------------------------------------------------------------
--------------------------
procedure emp_incr_Proc
is
Cursor e_cur is select empno, sal from emp;
v_empno emp.empno%type;
v_sal emp.sal%type;
v_incr_sal Number;
Begin
open e_cur;
loop
fetch e_cur into v_empno, v_sal; -- 7369, 900
exit when e_cur%notfound;
if emp_exp( v_empno ) >=10 then
v_incr_sal := v_sal * 0.5;
else
v_incr_sal := v_sal * 0.3;
end if;
Insert into Employ_Incr values ( v_empno, sysdate, emp_exp(v_empno),
v_incr_sal );
Update emp set sal = sal + v_incr_sal where empno = v_empno;
end loop;
close e_cur;
dbms_output.put_line( 'Employ Salary Incremented Successfully....');
End emp_incr_Proc;

22 rows selected.

** Dropping functions

Drop Function emp_exp;

PACKAGES :
**********

-> Package is a collection of Variables, Cursors, Procedures &


Functions

-> Packges are not supported parameters and It doesn't return any
values

-> Packages are supports Function Overloading, Data Abstraction, Data


Encapsulation & Inheritance

-> All created package names are stored in USER_OBJECTS & Bodies are
stored USER_SOURCE table

-> Packages are two types

I. PRE-DEFINED PACKAGES

-> There packages are defined by Oracle

ex: dbms_output, UTL_FILES, etc.,

II. USER-DEFINED PACKAGES

II. USER-DEFINED PACKAGES :


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

-> these packages are defined developer explicitely

-> User defined packages are classified into two parts

a. Package Specification

b. Package Body

a. Package Specification :
--------------------------

-> It holds declaration of variables, cursors, procedures & packages

b. Package body :
------------------

-> It contains definitions of package specification

Ex:-

-- write a user defined package program find sum of numbers &


multiplication of two numbers

Package specification :
-----------------------

Create or replace package my_pack


is
Procedure add_proc( x number, y number );
Function mul_fun( x number, y number ) return number;
End my_pack;
/

Package body :
--------------

Create or replace Package body my_pack


is

Procedure add_proc( x number, y number )


is
begin
dbms_output.put_line( 'Sum of Two Numbers = '||(x+y));
End add_proc;

Function mul_fun( x number, y number ) return number


is
Begin
Return ( x * y ) ;
End mul_fun;

End my_pack;
/

Calling Package Programs :


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

SQL> Exec my_pack.add_proc(100, 200 );


Sum of Two Numbers = 300

PL/SQL procedure successfully completed.

SQL> select my_pack.mul_fun( 100, 200 ) from dual;

MY_PACK.MUL_FUN(100,200)
------------------------
20000

I. COLUMN LEVEL FUNCTIONS :


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

-> These functions are applicable for each and every column values
-> Column Level Functions are classified into 3 types

i. NUMBER Functions

ii. CHARACTER Functions

iii. DATE Functions

i. NUMBER Functions :
---------------------

-> These functions are supports NUMARIC values only

ABS() :
-------

-> This function converts -ve value to +ve value

ex:-

SQL> select abs(-100) from emp;

ABS(-100)
----------
100
100
100
100
100
100
100
100
100
100
100
100
100
100

14 rows selected.

SQL> select abs(-100) from dept;

ABS(-100)
----------
100
100
100
100

SQL> select * from dual;

D
-
X

SQL>
SQL> select abs(-100) from dual;
ABS(-100)
----------
100

note: DUAL is one of the ORACLE pre-defined function and it contains one
record. So, our function is calling only one time.

SQRT() :
--------

-> returns SQRT value

ex:-

SQL> select abs(-100) from dual;

ABS(-100)
----------
100

SQL> select sqrt(25) from dual;

SQRT(25)
----------
5

SQL> select sqrt(-625) from dual;


select sqrt(-625) from dual
*
ERROR at line 1:
ORA-01428: argument '-625' is out of range

MOD() :
-------

-> This function returns Remainder

SQL> SELECT MOD(10,2) FROM DUAL;

MOD(10,2)
----------
0

SQL> SELECT MOD(10,3) FROM DUAL;

MOD(10,3)
----------
1

-- Waq to display who are getting ODD salaries

SQL> select * from emp where mod(sal,2)!=0;

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7566 JONES MANAGER 7839 02-APR-81 2975
20
SIGN() :
--------

-> It function returns if given value is +ve returns 1


-ve returns -1
0 returns 0

SQL> SELECT SIGN(-1000) FROM DUAL;

SIGN(-1000)
-----------
-1

SQL> SELECT SIGN(1000) FROM DUAL;

SIGN(1000)
----------
1

SQL> SELECT SIGN(0) FROM DUAL;

SIGN(0)
----------
0

SIN() :
-------

SELECT SIN(90) FROM DUAL;

cos() :
-------

select cos(90) from dual;

tan() :
-------

select tan(90) from dual;

ROUND() :
---------

-> this function used to rounded to nearest value

ex:-

SQL> select round(16.78) from dual; -- 7 >=5

ROUND(16.78)
------------
17

SQL> select round(16.48) from dual; -- 4 >=5 x

ROUND(16.48)
------------
16
-- to display after decimal part single digit

SQL> select round(16.796, 1) from dual; 9 >=5

ROUND(16.796,1)
---------------
16.8

SQL> select round(16.746,2) from dual;

ROUND(16.746,2)
---------------
16.75

TRUNC :-
--------

-> This function not rounded to nearest value

ex:-

SQL> select trunc(16.78) from dual;

TRUNC(16.78)
------------
16

SQL> select trunc(16.758,1) from dual;

TRUNC(16.758,1)
---------------
16.7

SQL> select trunc(16.987,2) from dual;

TRUNC(16.987,2)
---------------
16.98

16.35 -> 16

16.65 -> 17

-- waq to display each employee daily wages

SQL> select empno, sal / 30 from emp;

EMPNO SAL/30
---------- ----------
7369 26.6666667
7499 53.3333333
7521 41.6666667
7566 99.1666667
7654 41.6666667
7698 95
7782 81.6666667
7788 100
7839 166.666667
7844 50
7876 36.6666667
7900 31.6666667
7902 100
7934 43.3333333

14 rows selected.

SQL> select empno, round(sal / 30) from emp;

EMPNO ROUND(SAL/30)
---------- -------------
7369 27
7499 53
7521 42
7566 99
7654 42
7698 95
7782 82
7788 100
7839 167
7844 50
7876 37
7900 32
7902 100
7934 43

14 rows selected.

-- waq to display each employee experience up to till date

SQL> Select EMPNO, ROUND( (SYSDATE - HIREDATE)/365, 1 ) AS EXPERIENCE


FROM EMP;

EMPNO EXPERIENCE
---------- ----------
7369 42.9
7499 42.7
7521 42.7
7566 42.6
7654 42.1
7698 42.5
7782 42.4
7788 40.9
7839 41.9
7844 42.1
7876 40.8
7900 41.9
7902 41.9
7934 41.8

14 rows selected.

EXPERIENCE :- It is a column Alaise.

** Alaise is a temporary name and it is valid for that query only.

** Alaises are two types

i. column Alaise
ii. Table Alaise

i. Column Alaise :
------------------

-> Alaise Name is given to next to column name is called as Column


Alaise

ex:-

SQL> select empno as employ_no, ename as Employ_name, Sal as "Basic


Salary", Deptno Deptno from emp;

EMPLOY_NO EMPLOY_NAM Basic Salary DEPTNO


---------- ---------- ------------ ----------
7369 SMITH 800 20
7499 ALLEN 1600 30
7521 WARD 1250 30
7566 JONES 2975 20
7654 MARTIN 1250 30
7698 BLAKE 2850 30
7782 CLARK 2450 10
7788 SCOTT 3000 20
7839 KING 5000 10
7844 TURNER 1500 30
7876 ADAMS 1100 20
7900 JAMES 950 30
7902 FORD 3000 20
7934 MILLER 1300 10

14 rows selected.

note: if alaise contains morethan one word then should be placed in " "
and AS is optional

ii. Table Alaise :


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

-> Alaise name is given to next table name is called as Table Aalise

ex:- EMPLOY_MASTER_TABLE EMT, EMPLOYEE_TRANSACTION_TABLE ETT, etc.,

ii. CHARACTER FUNCTIONS :


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

-> These functions are supports only CHAR. values

LOWER() :
---------

-> This function converts any formated string to LOWER case

SQL> select lower('NARESH IT') FROM DUAL;

LOWER('NA
---------
naresh it
UPPER() :
---------

-> it converts any formated string to UPPER case

ex:-

SQL> select upper('naresh it') from dual;

UPPER('NA
---------
NARESH IT

INITCAP() :
-----------

-> it converts any formated string to INITIAL CAPITAL LETTER

ex:-

SQL> select initcap( 'NARESH IT' ) FROM DUAL;

INITCAP('
---------
Naresh It

-- waq to display SMITH employee record

SQL> select * from emp where lower(ename)='smith';

EMPNO ENAME JOB MGR HIREDATE SAL


COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------
- ----------
7369 SMITH CLERK 7902 17-DEC-80 800
20

LENGTH() :
----------

-> this function returns length of the string

SQL> select ename, lower(ename), upper(ename), initcap(ename),


length(ename) from emp;

ENAME LOWER(ENAM UPPER(ENAM INITCAP(EN LENGTH(ENAME)


---------- ---------- ---------- ---------- -------------
SMITH smith SMITH Smith 5
ALLEN allen ALLEN Allen 5
WARD ward WARD Ward 4
JONES jones JONES Jones 5
MARTIN martin MARTIN Martin 6
BLAKE blake BLAKE Blake 5
CLARK clark CLARK Clark 5
SCOTT scott SCOTT Scott 5
KING king KING King 4
TURNER turner TURNER Turner 6
ADAMS adams ADAMS Adams 5
JAMES james JAMES James 5
FORD ford FORD Ford 4
MILLER miller MILLER Miller 6

14 rows selected.

-- waq to display which employees names contains morethan 4 chars.

ASCII() :
---------

-> It converts CHAR value to equallent ASCII code

SQL> select ASCII('A') FROM DUAL;

ASCII('A')
----------
65

SQL> select ASCII('a') FROM DUAL;

ASCII('A')
----------
97

CHR() :
-------

-> it converts ASCII code to equallent CHAR code

SQL> select CHR(97) FROM DUAL;

C
-
a

SQL> select CHR(65) FROM DUAL;

C
-
A

LPAD() :
--------

-> it returns left side paddings ( spaces )

ex:-

SQL> select lpad('RAMA',10) FROM DUAL;

LPAD('RAMA
----------
RAMA

** to fill the spaces with special characters

SQL> select lpad('RAMA',10,'*') FROM DUAL;


LPAD('RAMA
----------
******RAMA

RPAD() :
--------

-> returns right side paddings

SQL> select rpad('RAMA',10,'*') FROM DUAL;

RPAD('RAMA
----------
RAMA******

-- to display both sides then to use NESTED FUNCTIONS

***RAMA***

SQL> select LPAD( rpad('RAMA',7,'*'), 10, '*') FROM DUAL;

LPAD(RPAD(
----------
***RAMA***

-- waq to display following format output

*****NARESH IT*****

LTRIM() :
---------

-> used to delete left side specified matching characters

SQL> select ltrim( 'AAAARAMA','A') FROM DUAL;

LTRI
----
RAMA

RTRIM() :
---------

-> used to delete right side specified matching characters

SQL> select rtrim( 'RAMAAAAAAA','A') FROM DUAL;

RTR
---
RAM

TRIM() :
--------

-> used to deletes both sides matching characters

SQL> select trim('A' FROM 'AAAARAMAAAAA') from dual;


TRI
---
RAM

note: by default All TRIM function deletes spaces

ex:-

SQL> select rtrim( 'RAMA ') FROM DUAL;

RTRI
----
RAMA

-- waq to display first name from given name

SACHIN TENDULKAR

SQL> SELECT RTRIM('SACHIN TENDULKAR','TENDULKAR') FROM DUAL;

RTRIM('
-------
SACHIN

-- waq to display Last name from given name

SACHIN TENDULKAR

-- waq to display Middle name from given name

RAMESH SACHIN TENDULKAR

REPLACE() :
-----------

-> this function replaces word by word

SQL> select replace('AXIS BANK','AXIS', 'ICICI') FROM DUAL;

REPLACE('A
----------
ICICI BANK

TRANSLATE() :
-------------

-> this function translates char. by char.

SQL> select translate('ABBCDD','ABCD','*&^%') FROM DUAL;

TRANSL
------
*&&^%%

-- write a package program to find given employee DEPT. NAME & his grade

Package Spefication :
---------------------

Create or replace package emp_pack


is
Procedure emp_dname ( p_empno emp.empno%type );
Function emp_grade ( p_empno emp.empno%type) return Varchar2;
End emp_pack;
/

Package Body :
--------------

Create or replace package body emp_pack


is
Procedure emp_dname ( p_empno emp.empno%type )
is
v_dname dept.dname%type;
Begin
select dname into v_dname from emp, dept where emp.deptno=dept.deptno
and empno = p_empno;
dbms_output.put_line( v_dname );
Exception
when no_data_found then
raise_application_error(-20001, 'Employ record not found.');
End emp_dname;

Function emp_grade ( p_empno emp.empno%type) return Varchar2


is
v_grade number;
Begin
Select grade into v_grade from emp, salgrade
where sal between losal and hisal
and
empno = p_empno;
return( p_empno|| ' Employee Grade is ' || v_grade);
Exception
when no_data_found then
return ('Employ Record Not Found.');
End emp_grade;

End emp_pack;
/

calling programs :
------------------

SQL> exec emp_pack.emp_dname(7839);

PL/SQL procedure successfully completed.

SQL> set serveroutput on


SQL> set verify off
SQL> exec emp_pack.emp_dname(7839);
ACCOUNTING

PL/SQL procedure successfully completed.

SQL> exec emp_pack.emp_dname(7369);


RESEARCH

PL/SQL procedure successfully completed.

SQL> exec emp_pack.emp_dname(9000);


BEGIN emp_pack.emp_dname(9000); END;

*
ERROR at line 1:
ORA-20001: Employ record not found.
ORA-06512: at "ORA8PM.EMP_PACK", line 11
ORA-06512: at line 1

SQL> select emp_pack.emp_grade(7839) from dual;

EMP_PACK.EMP_GRADE(7839)
-------------------------------------------------------------------------
------
7839 Employee Grade is 5

SQL> select emp_pack.emp_grade(7369) from dual;

EMP_PACK.EMP_GRADE(7369)
-------------------------------------------------------------------------
------
7369 Employee Grade is 2

SQL> select emp_pack.emp_grade(9000) from dual;

EMP_PACK.EMP_GRADE(9000)
-------------------------------------------------------------------------
------
Employ Record Not Found.

Packages are supports OOPs features :


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

Function OverLoading :
----------------------

-> Function Name is same and it supports different data types or No.of
Parameters is called as Function Overloading

-> Only Packages are supports Function Overloading

ex:-

Create or replace package fo_pack


is
function add_val( x number, y number ) return number;
function add_val( x number, y number, z number ) return number;
function add_val( str1 varchar2, str2 varchar2 ) return varchar2;
End fo_pack;
/

Package body :
--------------

Create or replace Package Body FO_PACK


is
function add_val( x number, y number ) return number
is
Begin
return( x + y );
End add_val;

function add_val( x number, y number, z number ) return number


is
Begin
return( x + y + z );
End add_val;

function add_val( str1 varchar2, str2 varchar2 ) return varchar2


is
Begin
return( str1||' '||str2 );
End add_val;
End fo_pack;
/

SQL> select fo_pack.add_val(100, 200 ) from dual;

FO_PACK.ADD_VAL(100,200)
------------------------
300

SQL> select fo_pack.add_val(100, 200, 500 ) from dual;

FO_PACK.ADD_VAL(100,200,500)
----------------------------
800

SQL> select fo_pack.add_val( 'naresh', 'it' ) from dual;

FO_PACK.ADD_VAL('NARESH','IT')
------------------------------------------------------------------
naresh it

Packages using CURSORS :


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

-> Packages are using REF CURSORs

-- Package program for to input deptno. and display corresponding


employee details

Package Specification :
-----------------------

Create or replace package P1


is
Type R_Cur is Ref Cursor;
End P1;
/

Create or replace procedure dept_Proc


( p_deptno emp.deptno%type )
is
v_cur P1.R_cur;
e emp%rowtype;
Begin
open v_cur for select * from emp where deptno = p_deptno;
loop
fetch v_cur into e;
exit when v_cur%notfound;
dbms_output.put_line( e.empno ||' '||e.ename||' '||e.job||'
'||e.sal||' '||e.hiredate||' '||e.deptno );
end loop;
close v_cur;
end dept_Proc;
/

temp_group_master
------------------

tempid version itemid index isactive


1 11 i1 1 null
2 12 i2 1 null

temp_value_version
-------------------

tempid versio itemid index


1 11 i1 1
3 21 i10 0

Table creation :
-----------------

create table temp_group_master( tempid varchar2(10), version


varchar2(10), itemid varchar2(10),
index_1 number(2), isactive number(2));

Insert into temp_group_master values( 1, 11, 'i1', 1, null );


Insert into temp_group_master values( 2, 12, 'i2', 1, null );

create table temp_value_verion( tempid varchar2(10), version


varchar2(10), itemid varchar2(10),
index_1 number(2));

Insert into temp_value_verion values( 1, 11, 'i1', 1 );


Insert into temp_value_verion values( 3, 21, 'i10', 0 );

select count(*) from temp_group_master tg, temp_value_verion tv


where tg.tempid = tv.tempid
and
tg.itemid = tv.itemid;

Packages using CURSORS :


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

-> Packages are using REF CURSORs

-- Package program for to input deptno. and display corresponding


employee details
Package Specification :
-----------------------

Create or replace package P1


is
Type R_Cur is Ref Cursor;
End P1;
/

Create or replace procedure dept_Proc


( p_deptno emp.deptno%type )
is
v_cur P1.R_cur;
e emp%rowtype;
Begin
open v_cur for select * from emp where deptno = p_deptno;
loop
fetch v_cur into e;
exit when v_cur%notfound;
dbms_output.put_line( e.empno ||' '||e.ename||' '||e.job||'
'||e.sal||' '||e.hiredate||' '||e.deptno );
end loop;
close v_cur;
end dept_Proc;
/

Exceution :
-----------

SQL> EXEC DEPT_PROC(10);


7782 CLARK MANAGER 3675 09-JUN-81 10
7839 KING PRESIDENT 9000 17-NOV-81 10
7934 MILLER CLERK 1950 23-JAN-82 10

PL/SQL procedure successfully completed.

SQL> EXEC DEPT_PROC(20);


7369 SMITH CLERK 1350 17-DEC-80 20
7566 JONES MANAGER 4612.5 02-APR-81 20
7876 ADAMS CLERK 1800 12-JAN-83 20
7902 FORD ANALYST 4650 03-DEC-81 20

PL/SQL procedure successfully completed.

** To see the created package names

SQL> select object_name from user_objects where object_type='PACKAGE';

OBJECT_NAME
-------------------------------------------------------------------------
---------------
MY_PACK
EMP_PACK
FO_PACK
P1
** to see the particular page body

SQL> select text from user_source where name='EMP_PACK';

TEXT
-------------------------------------------------------------------------
---------------------------
package emp_pack
is
Procedure emp_dname ( p_empno emp.empno%type );
Function emp_grade ( p_empno emp.empno%type) return Varchar2;
End emp_pack;
package body emp_pack
is
Procedure emp_dname ( p_empno emp.empno%type )
is
v_dname dept.dname%type;
Begin
select dname into v_dname from emp, dept where emp.deptno=dept.deptno
and empno = p_empno;
dbms_output.put_line( v_dname );
Exception
when no_data_found then
raise_application_error(-20001, 'Employ record not found.');
End emp_dname;

Function emp_grade ( p_empno emp.empno%type) return Varchar2


is
v_grade number;
Begin
Select grade into v_grade from emp, salgrade
where sal between losal and hisal
and
empno = p_empno;
return( p_empno|| ' Employee Grade is ' || v_grade);
Exception
when no_data_found then
return ('Employ Record Not Found.');
End emp_grade;

End emp_pack;

33 rows selected.

** Dropping packages

Drop Package my_pack;

Table creation :
-----------------

create table tg( tempid varchar2(10), version varchar2(10), itemid


varchar2(10),
index_1 number(2), isactive number(2));

Insert into tg values( 1, 11, 'i1', 1, null );


Insert into tg values( 2, 12, 'i2', 1, null );
Insert into tg values( 3, 21, 'i10', 0 ,NULL );

create table tv ( tempid varchar2(10), version varchar2(10), itemid


varchar2(10),
index_1 number(2));

Insert into tv values( 1, 11, 'i1', 1 );

Insert into tv values( 2, 12, 'i2', 1 );

SQL> select * from tg;

TEMPID VERSION ITEMID INDEX_1 ISACTIVE


---------- ---------- ---------- ------- --------
1 11 i1 1
2 12 i2 1
3 21 i10 0

SQL> select * from tv;

TEMPID VERSION ITEMID INDEX_1


---------- ---------- ---------- -------
1 11 i1 1
2 12 i2 1

SQL> UPDATE TG SET ISACTIVE= 0 WHERE EXISTS ( SELECT TEMPID FROM TV WHERE
TV.TEMPID=TG.TEMPID);

2 rows updated.

SQL> UPDATE TG SET ISACTIVE= 1 WHERE NOT EXISTS ( SELECT TEMPID FROM TV
WHERE TV.TEMPID=TG.TEMPID);

1 row updated.

or

SQL> UPDATE TG SET ISACTIVE= case when ( EXISTS ( SELECT 1 FROM TV WHERE
TV.TEMPID=TG.TEMPID and tg.itemid=tv.itemid)) then '0'
ELSE '1'
end;

SQL> SELECT * FROM TG;

TEMPID VERSION ITEMID INDEX_1 ISACTIVE


---------- ---------- ---------- ---------- ----------
1 11 i1 1 0
2 12 i2 1 0
3 21 i10 0 1

SQL> SELECT * FROM TV;

TEMPID VERSION ITEMID INDEX_1


---------- ---------- ---------- ----------
1 11 i1 1
2 12 i2 1

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only

-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------
Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(1), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

Tnos :
------

Create sequence tno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Proc view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Proc Credit( p_acno bank_mas.acno%type, tamt bank_trans.tamt%type );


-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( Sacno bank_trans.sacno%type,


Dacno bank_trans.dacno%type,
Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'


-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(1), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

Tnos :
------

Create sequence tno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is
-- Proc. body for to open a new account
Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;
-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
Begin

End min_stat;

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)


ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------
Create Table Bank_Trans( Tno number(10), sacno varchar2(10),
dacno varchar2(10), tdate date,
ttype char(1), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

Tnos :
------

Create sequence tno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is

-- Proc. body for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;
-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;

-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;

-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;

END BANK_PACK;
/

CALLING PACKAGE PROGRAMS :


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

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


-----------------------------
SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

V. CHECK BALANCE by using ACNO :


********************************
SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000

VI. MINI STATEMENT :


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

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************

PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.

VIII. AMT. transfer by using ACCNOs :


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

SQL> select * from bank_mas;


ACNO CNAME ADDR MOBILENO ODATE A
BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

IX. DELETE ACCOUNT :


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

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.

sample insertions :
-------------------

insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000


);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600

9 rows selected.

TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table

Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger

Oracle supports some trigger events...


a. before insert b. before update c.
before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table

iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


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

:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1


** in rollback segment column values are stored in preceeding ':'
operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters

DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.
SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-

-- Write a trigger program to raise error if updating salary is


lessthan existing salary

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'


-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(1), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

Tnos :
------

Create sequence tno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is
-- Proc. spec for to open a new account
Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is
-- Proc. body for to open a new account
Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;
-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;

-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;

END BANK_PACK;
/
CALLING PACKAGE PROGRAMS :
--------------------------

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;


ACNO CNAME ADDR MOBILENO ODATE A
BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

V. CHECK BALANCE by using ACNO :


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

SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000

VI. MINI STATEMENT :


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

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************

PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.

VIII. AMT. transfer by using ACCNOs :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

IX. DELETE ACCOUNT :


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

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.

sample insertions :
-------------------

insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000


);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600

9 rows selected.
TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table

Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger

Oracle supports some trigger events...

a. before insert b. before update c.


before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table

iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


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

:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

** in rollback segment column values are stored in preceeding ':'


operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters

DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.

SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-

-- Write a trigger program to raise error if updating salary is


lessthan existing salary

Create or replace trigger emp_upd_trig


Before Update on emp
for each row
begin
if :New.sal < :old.sal then
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary.');
end if;
end;
/

rollback segment :
-----------------
:old.empno=7902, :old.ename='ford'... :old.sal = 4650,...

:new.sal = 4000, :new.empno=7902

testing:-
*********

SQL> update emp set sal=4000 where empno=7902;


update emp set sal=4000 where empno=7902
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary.
ORA-06512: at "ORA8PM.EMP_UPD_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA8PM.EMP_UPD_TRIG'

SQL> update emp set sal=4700 where empno=7902;

1 row updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 23-SEP-23 4700 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

example 3 :
-----------

-- write a trigger program to take employee records backup

** create a employee backup table with the same structure of EMP table
without data

SQL> create table emp_backup as select * from emp where 1=2;

Table created.

SQL> desc emp_backup;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
EMPNO NOT NULL NUMBER(4)
ENAME
VARCHAR2(10)
JOB
VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL
NUMBER(7,2)
COMM
NUMBER(7,2)
DEPTNO NUMBER(2)

Trigger program :
-----------------

Create or replace trigger emp_del_trig


AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
Insert into emp_backup values ( :old.empno, :old.ename, :old.job,
:old.mgr,:old.hiredate, :old.sal,
:old.comm, :old.deptno);
dbms_output.put_line('Backup taken successfully.');

END;
/

ROLLBACK SEGMENT :-
-------------------

:old.empno=7902, :old.ename='ford',,,, :old.deptno=20

Testing :-

SQL> delete from emp where empno=7902;


Backup taken successfully.

1 row deleted.

SQL> select * from emp_backup;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 23-SEP-23 4700 20

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10

12 rows selected.

-- write a trigger program to generate employee no. automatically

sequence :
----------

create sequence my_seq


start with 1
increment by 1;

table creation:
---------------

create table emp_db( eno number(2), ename varchar2(10));

Trigger :-
-----------

Create or replace trigger emp_db_ins_trig


Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;
/

rollback segment :-
*******************

:new.eno=1, :new.ename='king'

Testing:-

SQL> select * from emp_db;

no rows selected

SQL> Insert into emp_db(ename) values ( 'king' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'scott' );


1 row created.

SQL> Insert into emp_db(ename) values ( 'james' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ ----------
1 king
2 scott
3 james

example 6:-
-----------

-> write a trigger program to peform DML operations on EMP table and
Transaction status should be
EMPLOYEE_STATUS table

Table creation :-
-----------------

SQL> Create table emp_status ( eno number(4), sdate date, status


varchar2(40));

Table created.

Trigger program :
----------------

Create or replace trigger EMP_DML_TRIG


After INSERT or UPDATE or DELETE
on EMP
For each row
Begin
if INSERTING then

Insert into emp_status values( :new.empno, sysdate, 'new employee


recruited.');
elsif UPDATING then

Insert into emp_status values( :new.empno, sysdate, 'employee record


updated.');

elsif DELETING then

Insert into emp_status values( :old.empno, sysdate, 'Employee


removed from the ORG.');

end if;

End;
/

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(1), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

Tnos :
------

Create sequence tno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);
-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is

-- Proc. body for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;

-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;

-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;

END BANK_PACK;
/

CALLING PACKAGE PROGRAMS :


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

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.
SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

V. CHECK BALANCE by using ACNO :


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

SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000

VI. MINI STATEMENT :


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

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************

PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.


VIII. AMT. transfer by using ACCNOs :
*************************************

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

IX. DELETE ACCOUNT :


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

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.


sample insertions :
-------------------

insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000


);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600

9 rows selected.

TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table


Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger

Oracle supports some trigger events...

a. before insert b. before update c.


before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table

iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


------------------
:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

** in rollback segment column values are stored in preceeding ':'


operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters

DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.

SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-

-- Write a trigger program to raise error if updating salary is


lessthan existing salary

Create or replace trigger emp_upd_trig


Before Update on emp
for each row
begin
if :New.sal < :old.sal then
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary.');
end if;
end;
/

rollback segment :
-----------------
:old.empno=7902, :old.ename='ford'... :old.sal = 4650,...

:new.sal = 4000, :new.empno=7902

testing:-
*********

SQL> update emp set sal=4000 where empno=7902;


update emp set sal=4000 where empno=7902
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary.
ORA-06512: at "ORA8PM.EMP_UPD_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA8PM.EMP_UPD_TRIG'

SQL> update emp set sal=4700 where empno=7902;


1 row updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 23-SEP-23 4700 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

example 3 :
-----------

-- write a trigger program to take employee records backup

** create a employee backup table with the same structure of EMP table
without data

SQL> create table emp_backup as select * from emp where 1=2;

Table created.

SQL> desc emp_backup;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
EMPNO NOT NULL NUMBER(4)
ENAME
VARCHAR2(10)
JOB
VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL
NUMBER(7,2)
COMM
NUMBER(7,2)
DEPTNO NUMBER(2)

Trigger program :
-----------------

Create or replace trigger emp_del_trig


AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
Insert into emp_backup values ( :old.empno, :old.ename, :old.job,
:old.mgr,:old.hiredate, :old.sal,
:old.comm, :old.deptno);
dbms_output.put_line('Backup taken successfully.');

END;
/

ROLLBACK SEGMENT :-
-------------------

:old.empno=7902, :old.ename='ford',,,, :old.deptno=20

Testing :-

SQL> delete from emp where empno=7902;


Backup taken successfully.

1 row deleted.

SQL> select * from emp_backup;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 23-SEP-23 4700 20

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10

12 rows selected.

-- write a trigger program to generate employee no. automatically

sequence :
----------

create sequence my_seq


start with 1
increment by 1;

table creation:
---------------

create table emp_db( eno number(2), ename varchar2(10));

Trigger :-
-----------

Create or replace trigger emp_db_ins_trig


Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;
/

rollback segment :-
*******************

:new.eno=1, :new.ename='king'

Testing:-

SQL> select * from emp_db;

no rows selected

SQL> Insert into emp_db(ename) values ( 'king' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'scott' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'james' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ ----------
1 king
2 scott
3 james

example 6:-
-----------

-> write a trigger program to peform DML operations on EMP table and
Transaction status should be
EMPLOYEE_STATUS table
Table creation :-
-----------------

SQL> Create table emp_status ( eno number(4), sdate date, status


varchar2(40));

Table created.

Trigger program :
----------------

Create or replace trigger EMP_DML_TRIG


After INSERT or UPDATE or DELETE
on EMP
For each row
Begin
if INSERTING then

Insert into emp_status values( :new.empno, sysdate, 'new employee


recruited.');
elsif UPDATING then

Insert into emp_status values( :new.empno, sysdate, 'employee record


updated.');

elsif DELETING then

Insert into emp_status values( :old.empno, sysdate, 'Employee


removed from the ORG.');

end if;

End;
/

II. STATEMENT LEVEL TRIGGERS :


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

-> Trigger program executed only once on entire table

-> In Statement Level triggers, Trigger Access specifiers( new & old )
not supported

ex:-

-- write a trigger program to restrict DML operations on EMP table


based on the following conditions.

i. Office timings are 10:00am to 5pm

ii. Weekends holidays

iii. On Public Holidays also holiday

Create a Holiday table with HOliday Dates :


*******************************************
Create table Holiday( Hdate date );

Insert into holiday values( '26-jan-23' );


Insert into holiday values( '15-aug-23' );
Insert into holiday values( '25-dec-23' );

SQL> select * from holiday;

HDATE
---------
26-JAN-23
15-AUG-23
25-DEC-23

Trigger program :
-----------------

Create or replace trigger holiday_trig


Before Insert or update or Delete
on Emp
Declare
cnt number;
Begin
if to_char(sysdate, 'hh24' ) not between 10 and 16 then
raise_application_error(-20001, 'Off-timings, Trans. are not
allowed.');
end if;

if to_char( sysdate, 'dy' ) in ( 'sat','sun') then


raise_application_error(-20002, 'Week-ends, Trans. are not
allowed.');
end if;

select count(hdate) into cnt from holiday


where trunc(hdate)=trunc(sysdate);
if cnt = 1 then
raise_application_error(-20003, 'Today Public Holiday, Trans. are
Not Allowed.');
end if;
End;
/

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20001: Off-timings, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 5
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20002: Week-ends, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 9
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'
SQL> Update emp set sal = sal + 1000;
Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20003: Today Public Holiday, Trans. are Not Allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 15
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 100;

14 rows updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 900 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1700 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1350 500 30
7566 JONES MANAGER 7839 02-APR-81 3075 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1350 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2950 30
7782 CLARK MANAGER 7839 09-JUN-81 2550 10
7788 SCOTT ANALYST 7566 09-DEC-82 3100 20
7839 KING PRESIDENT 17-NOV-81 5100 10
7844 TURNER SALESMAN 7698 08-SEP-81 1600 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1200 20
7900 JAMES CLERK 7698 03-DEC-81 1050 30
7902 FORD ANALYST 7566 03-DEC-81 3100 20
7934 MILLER CLERK 7782 23-JAN-82 1400 10

14 rows selected.

** why we are usign TRUNCATE on SYSDATE

SQL> select 1 from dual where trunc(to_date('27-oct-23') ) =


trunc(sysdate);

1
------
1

SQL> select 1 from dual where '27-oct-23' = trunc(sysdate);

1
------
1
ex:-

-- write a trigger program to not allow transactions on BANK_MASTER


TABLE based on following conditions

i. Bank timings 10:00 to 2:30 and 3:00pm to 4:00pm

ii. every 2nd & 4th Saturday days holidays


iii. On Public Holidays also holidays

III. INSTEAD OF TRIGGERS :


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

-> Generally we can write triggers on DB TABLES. But, we can write


triggers on VIEWS also.

-> To write triggers on VIEWS the event is INSTEAD OF

ex:-

-- On Complex views we can not perform DML commands, To allow DML


operations then to write INSTEAD TRIGGERS

Ex:-

Table creations :
-----------------

Create table std_db( std_id varchar2(10), sname varchar2(10) );

Create table std_marks( std_id varchar2(10), maths number(5,2), Phys


number(5,2), chem number(5,2));

Create a complex view :


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

Create or replace view std_comp_view


as
select s.std_id, s.sname, sm.maths, sm.phys, sm.chem
from std_db s, std_marks sm
where s.std_id = sm.std_id;

SQL> Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 );


Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 )
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table

note: on complex views DML operations are not allowed, to allow DML
operations then to write INSTEAD of triggers

Trigger :
---------

Create or replace trigger std_comp_view_trig


INSTEAD OF INSERT on std_comp_view
for each row
Begin
Insert into std_db values ( :new.std_id, :new.sname );
Insert into std_marks values ( :new.std_id, :new.maths, :New.phys,
:New.chem);
End;
/

SQL> SELECT * FROM STD_DB;


no rows selected

SQL> SELECT * FROM STD_MARKS;

no rows selected

SQL> insert into std_comp_view values ( 's1', 'anand', 90, 89, 80 );

1 row created.

SQL> select * from std_db;

STD_ID SNAME
---------- ----------
s1 anand

SQL> select * from std_marks;

STD_ID MATHS PHYS CHEM


---------- ------ ------ ------
s1 90 89 80

IV. SCHEMA LEVEL TRIGGERS :


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

-> These Triggers are also called as DDL triggers

-> To write Triggers on DDL commands that type of Triggers are called as
SCHEMA LEVEL TRIGGERS

SCHEMA :- Collection of db objects

Ex:-

-- Write a trigger program to restrict DROP command on DB OBJECTS

Create or replace Trigger drop_trig


Before DROP on SCHEMA
BEGIN
raise_application_error(-20001, 'Access Denied!!!!!');
END;
/

testing :
---------

SQL> DROP TABLE EMP;


DROP TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP VIEW MY_VIEW;


DROP VIEW MY_VIEW
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP PROCEDURE EMP_PROC;


DROP PROCEDURE EMP_PROC
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP TRIGGER HOLIDAY_TRIG;


DROP TRIGGER HOLIDAY_TRIG
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> drop trigger drop_trig;

Trigger dropped.

note: now DROP command is working

-- Trigger on TRUCATE Command

Create or replace trigger TRUNC_TRIG


BEFORE TRUNCATE ON SCHEMA
BEGIN
Raise_application_error(-20002, 'Truncate Command Restricted.....');
END;
/

Testing :-
***********

SQL> TRUNCATE TABLE EMP;


TRUNCATE TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20002: Truncate Command Restricted.....
ORA-06512: at line 2

V. DB LEVEL Triggers :
----------------------

-> These triggers are executed on entire USER

-> DB LEVEL trigger events are LOGON / LOGOFF events

ex:-
-- write a trigger program to main user login details

Table creation :
----------------

Create table login_details( tid number(2), user_id varchar2(10),


user_name varchar2(20), login_time timestamp,
logout_time timestamp, Wrk_hrs varchar2(10)
);

Sequence for to generate tids :


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

Create sequence tid_seq


start with 1
increment by 1;

Trigger on LOGIN :
------------------

Create or replace trigger login_trig


AFTER LOGON ON SCHEMA
Begin
Insert into login_details values ( tid_seq.nextval, uid, user, sysdate,
null, null );
End;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME LOGIN_TIME


LOGOUT_TIME WRK_HRS
---------- ---------- -------------------- -----------------
----------------- -----------------

1 49 ORA8PM 28-OCT-23 08.42.11.000000 PM

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:08:56.000000

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:09:09.000000

SQL> select substr( sysdate - login_time,12,8 ) from login_details where


tid=1;

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:26

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:30

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:33

LOGOUT TRIGGER :
----------------

Create or replace trigger logout_trig


BEFORE LOGOFF ON SCHEMA
BEGIN
Update login_details set logout_time = sysdate where tid=( select
max(tid) from login_details );
Update login_details set wrk_hrs = substr( sysdate - login_time, 12, 8
) where tid=( select max(tid) from login_details );
END;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
1 49 ORA8PM
28-OCT-23 08.42.11.000000 PM
28-OCT-23 08.53.33.000000 PM
00:11:22

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
3 49 ORA8PM
28-OCT-23 08.53.40.000000 PM

note: SCHEMA LEVEL & DB LEVEL Triggers are written and executed by DBA
only

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.


-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(1), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

Tnos :
------

Create sequence tno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------
Create or replace package Body BANK_PACK
is

-- Proc. body for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;

-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;

-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;
END BANK_PACK;
/

CALLING PACKAGE PROGRAMS :


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

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1
SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );
BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

V. CHECK BALANCE by using ACNO :


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

SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000

VI. MINI STATEMENT :


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

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************
PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.

VIII. AMT. transfer by using ACCNOs :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500
IX. DELETE ACCOUNT :
--------------------

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.

sample insertions :
-------------------

insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000


);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600
9 rows selected.

TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table

Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger

Oracle supports some trigger events...

a. before insert b. before update c.


before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table

iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


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

:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

** in rollback segment column values are stored in preceeding ':'


operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters
DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.

SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-

-- Write a trigger program to raise error if updating salary is


lessthan existing salary

Create or replace trigger emp_upd_trig


Before Update on emp
for each row
begin
if :New.sal < :old.sal then
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary.');
end if;
end;
/
rollback segment :
-----------------
:old.empno=7902, :old.ename='ford'... :old.sal = 4650,...

:new.sal = 4000, :new.empno=7902

testing:-
*********

SQL> update emp set sal=4000 where empno=7902;


update emp set sal=4000 where empno=7902
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary.
ORA-06512: at "ORA8PM.EMP_UPD_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA8PM.EMP_UPD_TRIG'

SQL> update emp set sal=4700 where empno=7902;

1 row updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 23-SEP-23 4700 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

example 3 :
-----------

-- write a trigger program to take employee records backup

** create a employee backup table with the same structure of EMP table
without data

SQL> create table emp_backup as select * from emp where 1=2;


Table created.

SQL> desc emp_backup;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
EMPNO NOT NULL NUMBER(4)
ENAME
VARCHAR2(10)
JOB
VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL
NUMBER(7,2)
COMM
NUMBER(7,2)
DEPTNO NUMBER(2)

Trigger program :
-----------------

Create or replace trigger emp_del_trig


AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
Insert into emp_backup values ( :old.empno, :old.ename, :old.job,
:old.mgr,:old.hiredate, :old.sal,
:old.comm, :old.deptno);
dbms_output.put_line('Backup taken successfully.');

END;
/

ROLLBACK SEGMENT :-
-------------------

:old.empno=7902, :old.ename='ford',,,, :old.deptno=20

Testing :-

SQL> delete from emp where empno=7902;


Backup taken successfully.

1 row deleted.

SQL> select * from emp_backup;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 23-SEP-23 4700 20

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10

12 rows selected.

-- write a trigger program to generate employee no. automatically

sequence :
----------

create sequence my_seq


start with 1
increment by 1;

table creation:
---------------

create table emp_db( eno number(2), ename varchar2(10));

Trigger :-
-----------

Create or replace trigger emp_db_ins_trig


Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;
/

rollback segment :-
*******************

:new.eno=1, :new.ename='king'

Testing:-

SQL> select * from emp_db;

no rows selected

SQL> Insert into emp_db(ename) values ( 'king' );


1 row created.

SQL> Insert into emp_db(ename) values ( 'scott' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'james' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ ----------
1 king
2 scott
3 james

example 6:-
-----------

-> write a trigger program to peform DML operations on EMP table and
Transaction status should be
EMPLOYEE_STATUS table

Table creation :-
-----------------

SQL> Create table emp_status ( eno number(4), sdate date, status


varchar2(40));

Table created.

Trigger program :
----------------

Create or replace trigger EMP_DML_TRIG


After INSERT or UPDATE or DELETE
on EMP
For each row
Begin
if INSERTING then

Insert into emp_status values( :new.empno, sysdate, 'new employee


recruited.');
elsif UPDATING then

Insert into emp_status values( :new.empno, sysdate, 'employee record


updated.');

elsif DELETING then

Insert into emp_status values( :old.empno, sysdate, 'Employee


removed from the ORG.');

end if;

End;
/
II. STATEMENT LEVEL TRIGGERS :
------------------------------

-> Trigger program executed only once on entire table

-> In Statement Level triggers, Trigger Access specifiers( new & old )
not supported

ex:-

-- write a trigger program to restrict DML operations on EMP table


based on the following conditions.

i. Office timings are 10:00am to 5pm

ii. Weekends holidays

iii. On Public Holidays also holiday

Create a Holiday table with HOliday Dates :


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

Create table Holiday( Hdate date );

Insert into holiday values( '26-jan-23' );


Insert into holiday values( '15-aug-23' );
Insert into holiday values( '25-dec-23' );

SQL> select * from holiday;

HDATE
---------
26-JAN-23
15-AUG-23
25-DEC-23

Trigger program :
-----------------

Create or replace trigger holiday_trig


Before Insert or update or Delete
on Emp
Declare
cnt number;
Begin
if to_char(sysdate, 'hh24' ) not between 10 and 16 then
raise_application_error(-20001, 'Off-timings, Trans. are not
allowed.');
end if;

if to_char( sysdate, 'dy' ) in ( 'sat','sun') then


raise_application_error(-20002, 'Week-ends, Trans. are not
allowed.');
end if;

select count(hdate) into cnt from holiday


where trunc(hdate)=trunc(sysdate);
if cnt = 1 then
raise_application_error(-20003, 'Today Public Holiday, Trans. are
Not Allowed.');
end if;
End;
/

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20001: Off-timings, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 5
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20002: Week-ends, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 9
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20003: Today Public Holiday, Trans. are Not Allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 15
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 100;

14 rows updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 900 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1700 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1350 500 30
7566 JONES MANAGER 7839 02-APR-81 3075 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1350 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2950 30
7782 CLARK MANAGER 7839 09-JUN-81 2550 10
7788 SCOTT ANALYST 7566 09-DEC-82 3100 20
7839 KING PRESIDENT 17-NOV-81 5100 10
7844 TURNER SALESMAN 7698 08-SEP-81 1600 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1200 20
7900 JAMES CLERK 7698 03-DEC-81 1050 30
7902 FORD ANALYST 7566 03-DEC-81 3100 20
7934 MILLER CLERK 7782 23-JAN-82 1400 10

14 rows selected.
** why we are usign TRUNCATE on SYSDATE

SQL> select 1 from dual where trunc(to_date('27-oct-23') ) =


trunc(sysdate);

1
------
1

SQL> select 1 from dual where '27-oct-23' = trunc(sysdate);

1
------
1
ex:-

-- write a trigger program to not allow transactions on BANK_MASTER


TABLE based on following conditions

i. Bank timings 10:00 to 2:30 and 3:00pm to 4:00pm

ii. every 2nd & 4th Saturday days holidays

iii. On Public Holidays also holidays

III. INSTEAD OF TRIGGERS :


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

-> Generally we can write triggers on DB TABLES. But, we can write


triggers on VIEWS also.

-> To write triggers on VIEWS the event is INSTEAD OF

ex:-

-- On Complex views we can not perform DML commands, To allow DML


operations then to write INSTEAD TRIGGERS

Ex:-

Table creations :
-----------------

Create table std_db( std_id varchar2(10), sname varchar2(10) );

Create table std_marks( std_id varchar2(10), maths number(5,2), Phys


number(5,2), chem number(5,2));

Create a complex view :


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

Create or replace view std_comp_view


as
select s.std_id, s.sname, sm.maths, sm.phys, sm.chem
from std_db s, std_marks sm
where s.std_id = sm.std_id;

SQL> Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 );


Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 )
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table

note: on complex views DML operations are not allowed, to allow DML
operations then to write INSTEAD of triggers

Trigger :
---------

Create or replace trigger std_comp_view_trig


INSTEAD OF INSERT on std_comp_view
for each row
Begin
Insert into std_db values ( :new.std_id, :new.sname );
Insert into std_marks values ( :new.std_id, :new.maths, :New.phys,
:New.chem);
End;
/

SQL> SELECT * FROM STD_DB;

no rows selected

SQL> SELECT * FROM STD_MARKS;

no rows selected

SQL> insert into std_comp_view values ( 's1', 'anand', 90, 89, 80 );

1 row created.

SQL> select * from std_db;

STD_ID SNAME
---------- ----------
s1 anand

SQL> select * from std_marks;

STD_ID MATHS PHYS CHEM


---------- ------ ------ ------
s1 90 89 80

IV. SCHEMA LEVEL TRIGGERS :


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

-> These Triggers are also called as DDL triggers

-> To write Triggers on DDL commands that type of Triggers are called as
SCHEMA LEVEL TRIGGERS

SCHEMA :- Collection of db objects

Ex:-

-- Write a trigger program to restrict DROP command on DB OBJECTS


Create or replace Trigger drop_trig
Before DROP on SCHEMA
BEGIN
raise_application_error(-20001, 'Access Denied!!!!!');
END;
/

testing :
---------

SQL> DROP TABLE EMP;


DROP TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP VIEW MY_VIEW;


DROP VIEW MY_VIEW
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP PROCEDURE EMP_PROC;


DROP PROCEDURE EMP_PROC
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP TRIGGER HOLIDAY_TRIG;


DROP TRIGGER HOLIDAY_TRIG
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> drop trigger drop_trig;

Trigger dropped.

note: now DROP command is working

-- Trigger on TRUCATE Command

Create or replace trigger TRUNC_TRIG


BEFORE TRUNCATE ON SCHEMA
BEGIN
Raise_application_error(-20002, 'Truncate Command Restricted.....');
END;
/

Testing :-
***********

SQL> TRUNCATE TABLE EMP;


TRUNCATE TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20002: Truncate Command Restricted.....
ORA-06512: at line 2

V. DB LEVEL Triggers :
----------------------

-> These triggers are executed on entire USER

-> DB LEVEL trigger events are LOGON / LOGOFF events

ex:-

-- write a trigger program to main user login details

Table creation :
----------------

Create table login_details( tid number(2), user_id varchar2(10),


user_name varchar2(20), login_time timestamp,
logout_time timestamp, Wrk_hrs varchar2(10)
);

Sequence for to generate tids :


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

Create sequence tid_seq


start with 1
increment by 1;

Trigger on LOGIN :
------------------

Create or replace trigger login_trig


AFTER LOGON ON SCHEMA
Begin
Insert into login_details values ( tid_seq.nextval, uid, user, sysdate,
null, null );
End;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME LOGIN_TIME


LOGOUT_TIME WRK_HRS
---------- ---------- -------------------- -----------------
----------------- -----------------

1 49 ORA8PM 28-OCT-23 08.42.11.000000 PM

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:08:56.000000

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:09:09.000000

SQL> select substr( sysdate - login_time,12,8 ) from login_details where


tid=1;

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:26

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:30

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:33

LOGOUT TRIGGER :
----------------

Create or replace trigger logout_trig


BEFORE LOGOFF ON SCHEMA
BEGIN
Update login_details set logout_time = sysdate where tid=( select
max(tid) from login_details );
Update login_details set wrk_hrs = substr( sysdate - login_time, 12, 8
) where tid=( select max(tid) from login_details );
END;
/
testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
1 49 ORA8PM
28-OCT-23 08.42.11.000000 PM
28-OCT-23 08.53.33.000000 PM
00:11:22

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
3 49 ORA8PM
28-OCT-23 08.53.40.000000 PM

note: SCHEMA LEVEL & DB LEVEL Triggers are written and executed by DBA
only

** All created trigger names are stored in USER_TRIGGERS/USER_OBJECTS

SQL> Select Object_name from user_objects where object_type='TRIGGER';

OBJECT_NAME
-------------------------------------------------------------------------
--------
STD_COMP_VIEW_TRIG
EMP_DB_INS_TRIG
TRUNC_TRIG
LOGIN_TRIG
LOGOUT_TRIG
or

SQL> SELECT TRIGGER_NAME FROM USER_TRIGGERS;

TRIGGER_NAME
------------------------------
EMP_DB_INS_TRIG
STD_COMP_VIEW_TRIG
LOGIN_TRIG
TRUNC_TRIG
LOGOUT_TRIG

** to see the particular trigger body

SQL> select text from user_source where name='EMP_DB_INS_TRIG';

TEXT
-------------------------------------------------------------------------
-------------------------
trigger emp_db_ins_trig
Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;

8 rows selected.

** DROPPING TRIGGERS :
**********************

syn:- DROP TRIGGER <trigger_name>;

ex:- DROP TRIGGER MY_TRIG;

note: on Single table max. 12 triggers are allowed

TRIGGER ON BANK_TRANS TABLE :


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

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi2 SCOTT SEC ###### 21-OCT-23 C 4500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
----------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

Validations :
-------------

-> Tno should be generate automatically

-> Source Accno column value is mandatory

-> If trans. type is 'AT' then DACCNO column value is mandatory

-> Trans. date will take today date only

-> Trans. type should be accept 'd', 'w' or 'at' only

-> Min. Trans. Amt Rs.1/-

-> Source accno is mandatory & should be available in bank_master table

-> if trans. type is 'd' (deposit) then balance should be update in


bank_mas table

-> if trans. type is 'w' ( withdraw) then

i. check the available balance, if succiffient balance then


allow the trans.
and update the balance in bank_master
table

ii. if in-sufficient balance then to raise error message

-> if trans. type is 'at' then

-> first check the balance then allow the transaction.

Sequence for to generate sequence nos. :


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

Create sequence tno_seq


start with 1
increment by 1;

Trigger Program :
-----------------

Create or replace trigger bank_trans_trig


Before Insert on Bank_Trans
for each row
decelare
scnt number;
Begin
If :new.Sacno is null then
raise_application_error(-20501, 'Source A/c No. is
Mandatory.....');
Elsif :new.ttype='at' then
if :new.Daccno is null then
raise_application_error(-20502, 'Destination A/c No. is
Mandatory.....');
end if;
End if;
:new.tdate := sysdate;
if :new.ttype not in ( 'd','w','at') then
raise_application_error(-20503, 'Invalid Transaction Type.....');
end if;
if :new.tamt<=0 then
raise_application_error (-20504, 'Min. Trans. Amt. Rs.1/-');
end if;

select count(*) into scnt from bank_master where acno = :new.sacno;


if scnt=0 then
raise_application_error( -20505, 'Invalid Source A.C No.');
end if;

if bank_pack.chk_bal(:new.sacno) >

End;
/

:tno=null, :sacno=sbi2, :dacno=null, :tdate=30-oct-2023, :ttype='d',


:tamt=1000

Insert into bank_trans(saccno, ttype, tamt ) values ( 'sbi2', 'd', 1000


);

existing bal new bal


3000 3500

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)


v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(2), tamt number(8,2)
);
Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement


Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,
p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is

-- Proc. body for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;

-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;
-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;
-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;

END BANK_PACK;
/

CALLING PACKAGE PROGRAMS :


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

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.


SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

V. CHECK BALANCE by using ACNO :


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

SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000
VI. MINI STATEMENT :
--------------------

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************

PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.

VIII. AMT. transfer by using ACCNOs :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.


SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

IX. DELETE ACCOUNT :


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

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.

sample insertions :
-------------------

insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000


);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);
SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600

9 rows selected.

TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table

Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger

Oracle supports some trigger events...

a. before insert b. before update c.


before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table
iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


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

:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

** in rollback segment column values are stored in preceeding ':'


operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters

DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.

SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-
-- Write a trigger program to raise error if updating salary is
lessthan existing salary

Create or replace trigger emp_upd_trig


Before Update on emp
for each row
begin
if :New.sal < :old.sal then
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary.');
end if;
end;
/

rollback segment :
-----------------
:old.empno=7902, :old.ename='ford'... :old.sal = 4650,...

:new.sal = 4000, :new.empno=7902

testing:-
*********

SQL> update emp set sal=4000 where empno=7902;


update emp set sal=4000 where empno=7902
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary.
ORA-06512: at "ORA8PM.EMP_UPD_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA8PM.EMP_UPD_TRIG'

SQL> update emp set sal=4700 where empno=7902;

1 row updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 23-SEP-23 4700 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.
example 3 :
-----------

-- write a trigger program to take employee records backup

** create a employee backup table with the same structure of EMP table
without data

SQL> create table emp_backup as select * from emp where 1=2;

Table created.

SQL> desc emp_backup;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
EMPNO NOT NULL NUMBER(4)
ENAME
VARCHAR2(10)
JOB
VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL
NUMBER(7,2)
COMM
NUMBER(7,2)
DEPTNO NUMBER(2)

Trigger program :
-----------------

Create or replace trigger emp_del_trig


AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
Insert into emp_backup values ( :old.empno, :old.ename, :old.job,
:old.mgr,:old.hiredate, :old.sal,
:old.comm, :old.deptno);
dbms_output.put_line('Backup taken successfully.');

END;
/

ROLLBACK SEGMENT :-
-------------------

:old.empno=7902, :old.ename='ford',,,, :old.deptno=20

Testing :-

SQL> delete from emp where empno=7902;


Backup taken successfully.

1 row deleted.

SQL> select * from emp_backup;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 23-SEP-23 4700 20

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10

12 rows selected.

-- write a trigger program to generate employee no. automatically

sequence :
----------

create sequence my_seq


start with 1
increment by 1;

table creation:
---------------

create table emp_db( eno number(2), ename varchar2(10));

Trigger :-
-----------

Create or replace trigger emp_db_ins_trig


Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;
/
rollback segment :-
*******************

:new.eno=1, :new.ename='king'

Testing:-

SQL> select * from emp_db;

no rows selected

SQL> Insert into emp_db(ename) values ( 'king' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'scott' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'james' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ ----------
1 king
2 scott
3 james

example 6:-
-----------

-> write a trigger program to peform DML operations on EMP table and
Transaction status should be
EMPLOYEE_STATUS table

Table creation :-
-----------------

SQL> Create table emp_status ( eno number(4), sdate date, status


varchar2(40));

Table created.

Trigger program :
----------------

Create or replace trigger EMP_DML_TRIG


After INSERT or UPDATE or DELETE
on EMP
For each row
Begin
if INSERTING then

Insert into emp_status values( :new.empno, sysdate, 'new employee


recruited.');
elsif UPDATING then

Insert into emp_status values( :new.empno, sysdate, 'employee record


updated.');

elsif DELETING then

Insert into emp_status values( :old.empno, sysdate, 'Employee


removed from the ORG.');

end if;

End;
/

II. STATEMENT LEVEL TRIGGERS :


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

-> Trigger program executed only once on entire table

-> In Statement Level triggers, Trigger Access specifiers( new & old )
not supported

ex:-

-- write a trigger program to restrict DML operations on EMP table


based on the following conditions.

i. Office timings are 10:00am to 5pm

ii. Weekends holidays

iii. On Public Holidays also holiday

Create a Holiday table with HOliday Dates :


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

Create table Holiday( Hdate date );

Insert into holiday values( '26-jan-23' );


Insert into holiday values( '15-aug-23' );
Insert into holiday values( '25-dec-23' );

SQL> select * from holiday;

HDATE
---------
26-JAN-23
15-AUG-23
25-DEC-23

Trigger program :
-----------------

Create or replace trigger holiday_trig


Before Insert or update or Delete
on Emp
Declare
cnt number;
Begin
if to_char(sysdate, 'hh24' ) not between 10 and 16 then
raise_application_error(-20001, 'Off-timings, Trans. are not
allowed.');
end if;

if to_char( sysdate, 'dy' ) in ( 'sat','sun') then


raise_application_error(-20002, 'Week-ends, Trans. are not
allowed.');
end if;

select count(hdate) into cnt from holiday


where trunc(hdate)=trunc(sysdate);
if cnt = 1 then
raise_application_error(-20003, 'Today Public Holiday, Trans. are
Not Allowed.');
end if;
End;
/

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20001: Off-timings, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 5
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20002: Week-ends, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 9
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20003: Today Public Holiday, Trans. are Not Allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 15
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 100;

14 rows updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 900 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1700 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1350 500 30
7566 JONES MANAGER 7839 02-APR-81 3075 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1350 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2950 30
7782 CLARK MANAGER 7839 09-JUN-81 2550 10
7788 SCOTT ANALYST 7566 09-DEC-82 3100 20
7839 KING PRESIDENT 17-NOV-81 5100 10
7844 TURNER SALESMAN 7698 08-SEP-81 1600 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1200 20
7900 JAMES CLERK 7698 03-DEC-81 1050 30
7902 FORD ANALYST 7566 03-DEC-81 3100 20
7934 MILLER CLERK 7782 23-JAN-82 1400 10

14 rows selected.

** why we are usign TRUNCATE on SYSDATE

SQL> select 1 from dual where trunc(to_date('27-oct-23') ) =


trunc(sysdate);

1
------
1

SQL> select 1 from dual where '27-oct-23' = trunc(sysdate);

1
------
1
ex:-

-- write a trigger program to not allow transactions on BANK_MASTER


TABLE based on following conditions

i. Bank timings 10:00 to 2:30 and 3:00pm to 4:00pm

ii. every 2nd & 4th Saturday days holidays

iii. On Public Holidays also holidays

III. INSTEAD OF TRIGGERS :


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

-> Generally we can write triggers on DB TABLES. But, we can write


triggers on VIEWS also.

-> To write triggers on VIEWS the event is INSTEAD OF

ex:-

-- On Complex views we can not perform DML commands, To allow DML


operations then to write INSTEAD TRIGGERS

Ex:-

Table creations :
-----------------

Create table std_db( std_id varchar2(10), sname varchar2(10) );


Create table std_marks( std_id varchar2(10), maths number(5,2), Phys
number(5,2), chem number(5,2));

Create a complex view :


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

Create or replace view std_comp_view


as
select s.std_id, s.sname, sm.maths, sm.phys, sm.chem
from std_db s, std_marks sm
where s.std_id = sm.std_id;

SQL> Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 );


Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 )
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table

note: on complex views DML operations are not allowed, to allow DML
operations then to write INSTEAD of triggers

Trigger :
---------

Create or replace trigger std_comp_view_trig


INSTEAD OF INSERT on std_comp_view
for each row
Begin
Insert into std_db values ( :new.std_id, :new.sname );
Insert into std_marks values ( :new.std_id, :new.maths, :New.phys,
:New.chem);
End;
/

SQL> SELECT * FROM STD_DB;

no rows selected

SQL> SELECT * FROM STD_MARKS;

no rows selected

SQL> insert into std_comp_view values ( 's1', 'anand', 90, 89, 80 );

1 row created.

SQL> select * from std_db;

STD_ID SNAME
---------- ----------
s1 anand

SQL> select * from std_marks;

STD_ID MATHS PHYS CHEM


---------- ------ ------ ------
s1 90 89 80
IV. SCHEMA LEVEL TRIGGERS :
---------------------------

-> These Triggers are also called as DDL triggers

-> To write Triggers on DDL commands that type of Triggers are called as
SCHEMA LEVEL TRIGGERS

SCHEMA :- Collection of db objects

Ex:-

-- Write a trigger program to restrict DROP command on DB OBJECTS

Create or replace Trigger drop_trig


Before DROP on SCHEMA
BEGIN
raise_application_error(-20001, 'Access Denied!!!!!');
END;
/

testing :
---------

SQL> DROP TABLE EMP;


DROP TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP VIEW MY_VIEW;


DROP VIEW MY_VIEW
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP PROCEDURE EMP_PROC;


DROP PROCEDURE EMP_PROC
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP TRIGGER HOLIDAY_TRIG;


DROP TRIGGER HOLIDAY_TRIG
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> drop trigger drop_trig;

Trigger dropped.

note: now DROP command is working

-- Trigger on TRUCATE Command

Create or replace trigger TRUNC_TRIG


BEFORE TRUNCATE ON SCHEMA
BEGIN
Raise_application_error(-20002, 'Truncate Command Restricted.....');
END;
/

Testing :-
***********

SQL> TRUNCATE TABLE EMP;


TRUNCATE TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20002: Truncate Command Restricted.....
ORA-06512: at line 2

V. DB LEVEL Triggers :
----------------------

-> These triggers are executed on entire USER

-> DB LEVEL trigger events are LOGON / LOGOFF events

ex:-

-- write a trigger program to main user login details

Table creation :
----------------

Create table login_details( tid number(2), user_id varchar2(10),


user_name varchar2(20), login_time timestamp,
logout_time timestamp, Wrk_hrs varchar2(10)
);

Sequence for to generate tids :


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

Create sequence tid_seq


start with 1
increment by 1;

Trigger on LOGIN :
------------------
Create or replace trigger login_trig
AFTER LOGON ON SCHEMA
Begin
Insert into login_details values ( tid_seq.nextval, uid, user, sysdate,
null, null );
End;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME LOGIN_TIME


LOGOUT_TIME WRK_HRS
---------- ---------- -------------------- -----------------
----------------- -----------------

1 49 ORA8PM 28-OCT-23 08.42.11.000000 PM

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:08:56.000000

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:09:09.000000

SQL> select substr( sysdate - login_time,12,8 ) from login_details where


tid=1;

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:26

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:30

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:33
LOGOUT TRIGGER :
----------------

Create or replace trigger logout_trig


BEFORE LOGOFF ON SCHEMA
BEGIN
Update login_details set logout_time = sysdate where tid=( select
max(tid) from login_details );
Update login_details set wrk_hrs = substr( sysdate - login_time, 12, 8
) where tid=( select max(tid) from login_details );
END;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
1 49 ORA8PM
28-OCT-23 08.42.11.000000 PM
28-OCT-23 08.53.33.000000 PM
00:11:22

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
3 49 ORA8PM
28-OCT-23 08.53.40.000000 PM

note: SCHEMA LEVEL & DB LEVEL Triggers are written and executed by DBA
only
** All created trigger names are stored in USER_TRIGGERS/USER_OBJECTS

SQL> Select Object_name from user_objects where object_type='TRIGGER';

OBJECT_NAME
-------------------------------------------------------------------------
--------
STD_COMP_VIEW_TRIG
EMP_DB_INS_TRIG
TRUNC_TRIG
LOGIN_TRIG
LOGOUT_TRIG

or

SQL> SELECT TRIGGER_NAME FROM USER_TRIGGERS;

TRIGGER_NAME
------------------------------
EMP_DB_INS_TRIG
STD_COMP_VIEW_TRIG
LOGIN_TRIG
TRUNC_TRIG
LOGOUT_TRIG

** to see the particular trigger body

SQL> select text from user_source where name='EMP_DB_INS_TRIG';

TEXT
-------------------------------------------------------------------------
-------------------------
trigger emp_db_ins_trig
Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;

8 rows selected.

** DROPPING TRIGGERS :
**********************

syn:- DROP TRIGGER <trigger_name>;

ex:- DROP TRIGGER MY_TRIG;

note: on Single table max. 12 triggers are allowed

TRIGGER ON BANK_TRANS TABLE :


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

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi2 SCOTT SEC ###### 21-OCT-23 C 4500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
----------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

Validations :
-------------

-> Tno should be generate automatically

-> Source Accno column value is mandatory

-> If trans. type is 'AT' then DACCNO column value is mandatory

-> Trans. date will take today date only

-> Trans. type should be accept 'd', 'w' or 'at' only

-> Min. Trans. Amt Rs.1/-

-> Source accno is mandatory & should be available in bank_master table

-> if trans. type is 'd' (deposit) then balance should be update in


bank_mas table

-> if trans. type is 'w' ( withdraw) then

i. check the available balance, if sufficient balance then


allow the trans.
and update the balance in bank_master
table

ii. if in-sufficient balance then to raise error message

-> if trans. type is 'at' then

-> first check the balance then allow the transaction.


-> if customer completed morethan 3 withdraws in a month then next
trans. onwards to charge RS.20/- extra

Sequence for to generate sequence nos. :


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

Create sequence tno_seq


start with 1
increment by 1;

Trigger Program :
-----------------

Create or replace trigger bank_trans_trig


Before Insert on Bank_Trans
for each row
declare
scnt number;
no_of_withdraws number;
Begin
If :new.Sacno is null then
raise_application_error(-20501, 'Source A/c No. is
Mandatory.....');
Elsif :new.ttype='at' then
if :new.Dacno is null then
raise_application_error(-20502, 'Destination A/c No. is
Mandatory.....');
end if;
End if;
:new.tdate := sysdate;
if :new.ttype not in ( 'd','w','at') then
raise_application_error(-20503, 'Invalid Transaction Type.....');
end if;
if :new.tamt<=0 then
raise_application_error (-20504, 'Min. Trans. Amt. Rs.1/-');
end if;

select count(*) into scnt from bank_mas where acno = :new.sacno;


if scnt=0 then
raise_application_error( -20505, 'Invalid Source A/c No.');
end if;

if :new.ttype='d' then
Bank_Pack.credit( :new.sacno, :new.tamt ); -- credit
procedure is calling
elsif :new.ttype='w' then

Select count(*) into no_of_withdraws from bank_trans


where sacno = :new.sacno
and
ttype = 'w'
and
to_char(tdate,'mm-yyyy') = to_char(sysdate,'mm-
yyyy' );
if no_of_withdraws >=3 then
:new.tamt := :new.tamt + 20;
end if;

if ( bank_pack.chk_bal(:new.sacno) - :new.tamt ) >0 then


Bank_Pack.debit( :new.sacno, :new.tamt );
else
raise_application_error(-20506, 'In-sufficient Balance and your
withdraw power is Rs.'||bank_pack.chk_bal(:new.sacno));
end if;
elsif :new.ttype='at' then
if ( bank_pack.chk_bal(:new.sacno) - :new.tamt ) >0 then
Bank_Pack.Acc_trans( :new.sacno, :new.dacno, :new.tamt );
else
raise_application_error(-20506, 'In-sufficient Balance and your
Transfer power is Rs.'||bank_pack.chk_bal(:new.sacno));
end if;
end if;
:new.tno := tno_seq.nextval;
End;
/

Testing :
---------

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi1 SCOTT SEC ###### 21-OCT-23 C 6500
sbi2 KING HYD ###### 31-OCT-23 S 1500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

SQL>
SQL> insert into bank_trans(sacno, ttype, tamt ) values ( 'sbi1', 'd',
1000 );
amt. deposited.

1 row created.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi1 SCOTT SEC ###### 21-OCT-23 C 7500
sbi2 KING HYD ###### 31-OCT-23 S 1500
SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


------ ---------- ---------- --------- -- ------
1 sbi1 31-OCT-23 d 1000

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


-------------------
-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------

Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(2), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.


Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type
);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is

-- Proc. body for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;

-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;

-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;

END BANK_PACK;
/

CALLING PACKAGE PROGRAMS :


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

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.
SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

V. CHECK BALANCE by using ACNO :


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

SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000

VI. MINI STATEMENT :


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

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************

PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.


VIII. AMT. transfer by using ACCNOs :
*************************************

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

IX. DELETE ACCOUNT :


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

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.


sample insertions :
-------------------

insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000


);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600

9 rows selected.

TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table


Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger

Oracle supports some trigger events...

a. before insert b. before update c.


before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table

iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


------------------
:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

** in rollback segment column values are stored in preceeding ':'


operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters

DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.

SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-

-- Write a trigger program to raise error if updating salary is


lessthan existing salary

Create or replace trigger emp_upd_trig


Before Update on emp
for each row
begin
if :New.sal < :old.sal then
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary.');
end if;
end;
/

rollback segment :
-----------------
:old.empno=7902, :old.ename='ford'... :old.sal = 4650,...

:new.sal = 4000, :new.empno=7902

testing:-
*********

SQL> update emp set sal=4000 where empno=7902;


update emp set sal=4000 where empno=7902
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary.
ORA-06512: at "ORA8PM.EMP_UPD_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA8PM.EMP_UPD_TRIG'

SQL> update emp set sal=4700 where empno=7902;


1 row updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 23-SEP-23 4700 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

example 3 :
-----------

-- write a trigger program to take employee records backup

** create a employee backup table with the same structure of EMP table
without data

SQL> create table emp_backup as select * from emp where 1=2;

Table created.

SQL> desc emp_backup;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
EMPNO NOT NULL NUMBER(4)
ENAME
VARCHAR2(10)
JOB
VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL
NUMBER(7,2)
COMM
NUMBER(7,2)
DEPTNO NUMBER(2)

Trigger program :
-----------------

Create or replace trigger emp_del_trig


AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
Insert into emp_backup values ( :old.empno, :old.ename, :old.job,
:old.mgr,:old.hiredate, :old.sal,
:old.comm, :old.deptno);
dbms_output.put_line('Backup taken successfully.');

END;
/

ROLLBACK SEGMENT :-
-------------------

:old.empno=7902, :old.ename='ford',,,, :old.deptno=20

Testing :-

SQL> delete from emp where empno=7902;


Backup taken successfully.

1 row deleted.

SQL> select * from emp_backup;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 23-SEP-23 4700 20

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10

12 rows selected.

-- write a trigger program to generate employee no. automatically

sequence :
----------

create sequence my_seq


start with 1
increment by 1;

table creation:
---------------

create table emp_db( eno number(2), ename varchar2(10));

Trigger :-
-----------

Create or replace trigger emp_db_ins_trig


Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;
/

rollback segment :-
*******************

:new.eno=1, :new.ename='king'

Testing:-

SQL> select * from emp_db;

no rows selected

SQL> Insert into emp_db(ename) values ( 'king' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'scott' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'james' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ ----------
1 king
2 scott
3 james

example 6:-
-----------

-> write a trigger program to peform DML operations on EMP table and
Transaction status should be
EMPLOYEE_STATUS table
Table creation :-
-----------------

SQL> Create table emp_status ( eno number(4), sdate date, status


varchar2(40));

Table created.

Trigger program :
----------------

Create or replace trigger EMP_DML_TRIG


After INSERT or UPDATE or DELETE
on EMP
For each row
Begin
if INSERTING then

Insert into emp_status values( :new.empno, sysdate, 'new employee


recruited.');
elsif UPDATING then

Insert into emp_status values( :new.empno, sysdate, 'employee record


updated.');

elsif DELETING then

Insert into emp_status values( :old.empno, sysdate, 'Employee


removed from the ORG.');

end if;

End;
/

II. STATEMENT LEVEL TRIGGERS :


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

-> Trigger program executed only once on entire table

-> In Statement Level triggers, Trigger Access specifiers( new & old )
not supported

ex:-

-- write a trigger program to restrict DML operations on EMP table


based on the following conditions.

i. Office timings are 10:00am to 5pm

ii. Weekends holidays

iii. On Public Holidays also holiday

Create a Holiday table with HOliday Dates :


*******************************************
Create table Holiday( Hdate date );

Insert into holiday values( '26-jan-23' );


Insert into holiday values( '15-aug-23' );
Insert into holiday values( '25-dec-23' );

SQL> select * from holiday;

HDATE
---------
26-JAN-23
15-AUG-23
25-DEC-23

Trigger program :
-----------------

Create or replace trigger holiday_trig


Before Insert or update or Delete
on Emp
Declare
cnt number;
Begin
if to_char(sysdate, 'hh24' ) not between 10 and 16 then
raise_application_error(-20001, 'Off-timings, Trans. are not
allowed.');
end if;

if to_char( sysdate, 'dy' ) in ( 'sat','sun') then


raise_application_error(-20002, 'Week-ends, Trans. are not
allowed.');
end if;

select count(hdate) into cnt from holiday


where trunc(hdate)=trunc(sysdate);
if cnt = 1 then
raise_application_error(-20003, 'Today Public Holiday, Trans. are
Not Allowed.');
end if;
End;
/

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20001: Off-timings, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 5
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20002: Week-ends, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 9
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'
SQL> Update emp set sal = sal + 1000;
Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20003: Today Public Holiday, Trans. are Not Allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 15
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 100;

14 rows updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 900 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1700 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1350 500 30
7566 JONES MANAGER 7839 02-APR-81 3075 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1350 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2950 30
7782 CLARK MANAGER 7839 09-JUN-81 2550 10
7788 SCOTT ANALYST 7566 09-DEC-82 3100 20
7839 KING PRESIDENT 17-NOV-81 5100 10
7844 TURNER SALESMAN 7698 08-SEP-81 1600 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1200 20
7900 JAMES CLERK 7698 03-DEC-81 1050 30
7902 FORD ANALYST 7566 03-DEC-81 3100 20
7934 MILLER CLERK 7782 23-JAN-82 1400 10

14 rows selected.

** why we are usign TRUNCATE on SYSDATE

SQL> select 1 from dual where trunc(to_date('27-oct-23') ) =


trunc(sysdate);

1
------
1

SQL> select 1 from dual where '27-oct-23' = trunc(sysdate);

1
------
1
ex:-

-- write a trigger program to not allow transactions on BANK_MASTER


TABLE based on following conditions

i. Bank timings 10:00 to 2:30 and 3:00pm to 4:00pm

ii. every 2nd & 4th Saturday days holidays


iii. On Public Holidays also holidays

III. INSTEAD OF TRIGGERS :


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

-> Generally we can write triggers on DB TABLES. But, we can write


triggers on VIEWS also.

-> To write triggers on VIEWS the event is INSTEAD OF

ex:-

-- On Complex views we can not perform DML commands, To allow DML


operations then to write INSTEAD TRIGGERS

Ex:-

Table creations :
-----------------

Create table std_db( std_id varchar2(10), sname varchar2(10) );

Create table std_marks( std_id varchar2(10), maths number(5,2), Phys


number(5,2), chem number(5,2));

Create a complex view :


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

Create or replace view std_comp_view


as
select s.std_id, s.sname, sm.maths, sm.phys, sm.chem
from std_db s, std_marks sm
where s.std_id = sm.std_id;

SQL> Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 );


Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 )
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table

note: on complex views DML operations are not allowed, to allow DML
operations then to write INSTEAD of triggers

Trigger :
---------

Create or replace trigger std_comp_view_trig


INSTEAD OF INSERT on std_comp_view
for each row
Begin
Insert into std_db values ( :new.std_id, :new.sname );
Insert into std_marks values ( :new.std_id, :new.maths, :New.phys,
:New.chem);
End;
/

SQL> SELECT * FROM STD_DB;


no rows selected

SQL> SELECT * FROM STD_MARKS;

no rows selected

SQL> insert into std_comp_view values ( 's1', 'anand', 90, 89, 80 );

1 row created.

SQL> select * from std_db;

STD_ID SNAME
---------- ----------
s1 anand

SQL> select * from std_marks;

STD_ID MATHS PHYS CHEM


---------- ------ ------ ------
s1 90 89 80

IV. SCHEMA LEVEL TRIGGERS :


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

-> These Triggers are also called as DDL triggers

-> To write Triggers on DDL commands that type of Triggers are called as
SCHEMA LEVEL TRIGGERS

SCHEMA :- Collection of db objects

Ex:-

-- Write a trigger program to restrict DROP command on DB OBJECTS

Create or replace Trigger drop_trig


Before DROP on SCHEMA
BEGIN
raise_application_error(-20001, 'Access Denied!!!!!');
END;
/

testing :
---------

SQL> DROP TABLE EMP;


DROP TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP VIEW MY_VIEW;


DROP VIEW MY_VIEW
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP PROCEDURE EMP_PROC;


DROP PROCEDURE EMP_PROC
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP TRIGGER HOLIDAY_TRIG;


DROP TRIGGER HOLIDAY_TRIG
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> drop trigger drop_trig;

Trigger dropped.

note: now DROP command is working

-- Trigger on TRUCATE Command

Create or replace trigger TRUNC_TRIG


BEFORE TRUNCATE ON SCHEMA
BEGIN
Raise_application_error(-20002, 'Truncate Command Restricted.....');
END;
/

Testing :-
***********

SQL> TRUNCATE TABLE EMP;


TRUNCATE TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20002: Truncate Command Restricted.....
ORA-06512: at line 2

V. DB LEVEL Triggers :
----------------------

-> These triggers are executed on entire USER

-> DB LEVEL trigger events are LOGON / LOGOFF events

ex:-
-- write a trigger program to main user login details

Table creation :
----------------

Create table login_details( tid number(2), user_id varchar2(10),


user_name varchar2(20), login_time timestamp,
logout_time timestamp, Wrk_hrs varchar2(10)
);

Sequence for to generate tids :


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

Create sequence tid_seq


start with 1
increment by 1;

Trigger on LOGIN :
------------------

Create or replace trigger login_trig


AFTER LOGON ON SCHEMA
Begin
Insert into login_details values ( tid_seq.nextval, uid, user, sysdate,
null, null );
End;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME LOGIN_TIME


LOGOUT_TIME WRK_HRS
---------- ---------- -------------------- -----------------
----------------- -----------------

1 49 ORA8PM 28-OCT-23 08.42.11.000000 PM

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:08:56.000000

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:09:09.000000

SQL> select substr( sysdate - login_time,12,8 ) from login_details where


tid=1;

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:26

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:30

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:33

LOGOUT TRIGGER :
----------------

Create or replace trigger logout_trig


BEFORE LOGOFF ON SCHEMA
BEGIN
Update login_details set logout_time = sysdate where tid=( select
max(tid) from login_details );
Update login_details set wrk_hrs = substr( sysdate - login_time, 12, 8
) where tid=( select max(tid) from login_details );
END;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
1 49 ORA8PM
28-OCT-23 08.42.11.000000 PM
28-OCT-23 08.53.33.000000 PM
00:11:22

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
3 49 ORA8PM
28-OCT-23 08.53.40.000000 PM

note: SCHEMA LEVEL & DB LEVEL Triggers are written and executed by DBA
only

** All created trigger names are stored in USER_TRIGGERS/USER_OBJECTS

SQL> Select Object_name from user_objects where object_type='TRIGGER';

OBJECT_NAME
-------------------------------------------------------------------------
--------
STD_COMP_VIEW_TRIG
EMP_DB_INS_TRIG
TRUNC_TRIG
LOGIN_TRIG
LOGOUT_TRIG

or

SQL> SELECT TRIGGER_NAME FROM USER_TRIGGERS;

TRIGGER_NAME
------------------------------
EMP_DB_INS_TRIG
STD_COMP_VIEW_TRIG
LOGIN_TRIG
TRUNC_TRIG
LOGOUT_TRIG

** to see the particular trigger body

SQL> select text from user_source where name='EMP_DB_INS_TRIG';

TEXT
-------------------------------------------------------------------------
-------------------------
trigger emp_db_ins_trig
Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;

8 rows selected.

** DROPPING TRIGGERS :
**********************

syn:- DROP TRIGGER <trigger_name>;

ex:- DROP TRIGGER MY_TRIG;

note: on Single table max. 12 triggers are allowed

TRIGGER ON BANK_TRANS TABLE :


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

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi2 SCOTT SEC ###### 21-OCT-23 C 4500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
----------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

Validations :
-------------

-> Tno should be generate automatically

-> Source Accno column value is mandatory

-> If trans. type is 'AT' then DACCNO column value is mandatory

-> Trans. date will take today date only

-> Trans. type should be accept 'd', 'w' or 'at' only

-> Min. Trans. Amt Rs.1/-


-> Source accno is mandatory & should be available in bank_master table

-> if trans. type is 'd' (deposit) then balance should be update in


bank_mas table

-> if trans. type is 'w' ( withdraw) then

i. check the available balance, if sufficient balance then


allow the trans.
and update the balance in bank_master
table

ii. if in-sufficient balance then to raise error message

-> if trans. type is 'at' then

-> first check the balance then allow the transaction.

-> if customer completed morethan 3 withdraws in a month then next


trans. onwards to charge RS.20/- extra

Sequence for to generate sequence nos. :


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

Create sequence tno_seq


start with 1
increment by 1;

Trigger Program :
-----------------

Create or replace trigger bank_trans_trig


Before Insert on Bank_Trans
for each row
declare
scnt number;
no_of_withdraws number;
Begin
If :new.Sacno is null then
raise_application_error(-20501, 'Source A/c No. is
Mandatory.....');
Elsif :new.ttype='at' then
if :new.Dacno is null then
raise_application_error(-20502, 'Destination A/c No. is
Mandatory.....');
end if;
End if;
:new.tdate := sysdate;
if :new.ttype not in ( 'd','w','at') then
raise_application_error(-20503, 'Invalid Transaction Type.....');
end if;
if :new.tamt<=0 then
raise_application_error (-20504, 'Min. Trans. Amt. Rs.1/-');
end if;
select count(*) into scnt from bank_mas where acno = :new.sacno;
if scnt=0 then
raise_application_error( -20505, 'Invalid Source A/c No.');
end if;

if :new.ttype='d' then
Bank_Pack.credit( :new.sacno, :new.tamt ); -- credit
procedure is calling
elsif :new.ttype='w' then

Select count(*) into no_of_withdraws from bank_trans


where sacno = :new.sacno
and
ttype = 'w'
and
to_char(tdate,'mm-yyyy') = to_char(sysdate,'mm-
yyyy' );
if no_of_withdraws >=3 then
:new.tamt := :new.tamt + 20;
end if;

if ( bank_pack.chk_bal(:new.sacno) - :new.tamt ) >0 then


Bank_Pack.debit( :new.sacno, :new.tamt );
else
raise_application_error(-20506, 'In-sufficient Balance and your
withdraw power is Rs.'||bank_pack.chk_bal(:new.sacno));
end if;
elsif :new.ttype='at' then
if ( bank_pack.chk_bal(:new.sacno) - :new.tamt ) >0 then
Bank_Pack.Acc_trans( :new.sacno, :new.dacno, :new.tamt );
else
raise_application_error(-20506, 'In-sufficient Balance and your
Transfer power is Rs.'||bank_pack.chk_bal(:new.sacno));
end if;
end if;
:new.tno := tno_seq.nextval;
End;
/

Testing :
---------

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi1 SCOTT SEC ###### 21-OCT-23 C 6500
sbi2 KING HYD ###### 31-OCT-23 S 1500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

DEPOSIT AMT :
*************

SQL> insert into bank_trans(sacno, ttype, tamt ) values ( 'sbi1', 'd',


1000 );
amt. deposited.

1 row created.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi1 SCOTT SEC ###### 21-OCT-23 C 7500
sbi2 KING HYD ###### 31-OCT-23 S 1500

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


------ ---------- ---------- --------- -- ------
1 sbi1 31-OCT-23 d 1000

Withdraw amount :
*****************

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
7500
sbi2 KING HYD 9000994007 31-OCT-23 S
1500

SQL> SELECT * FROM BANK_TRANS;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1', 'w',
600 );
amt. withdraw successfully

1 row created.

SQL> SELECT * FROM BANK_MAS;


ACNO CNAME ADDR MOBILENO ODATE A
BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
6900
sbi2 KING HYD 9000994007 31-OCT-23 S
1500

SQL> SELECT * FROM BANK_TRANS;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600

Amt.Transfer :
--------------

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
6900
sbi2 KING HYD 9000994007 31-OCT-23 S
1500

SQL> SELECT * FROM BANK_TRANS;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600

SQL> insert into bank_trans( sacno, dacno, ttype, tamt ) values ( 'sbi1',
'sbi2', 'at', 1500 );
amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

1 row created.

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600
3 sbi1 sbi2 01-NOV-23 at 1500

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
5400
sbi2 KING HYD 9000994007 31-OCT-23 S
3000

INVALID INPUT :
***************

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
5400
sbi2 KING HYD 9000994007 31-OCT-23 S
3000

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi10','d',


15000 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi10','d', 15000
)
*
ERROR at line 1:
ORA-20505: Invalid Source A/c No.
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 22
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

Invalid ttype :
---------------

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','x',


15000 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','x', 15000 )
*
ERROR at line 1:
ORA-20503: Invalid Transaction Type.....
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 14
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

Wrong amt input :


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

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


15000 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w', 15000 )
*
ERROR at line 1:
ORA-20506: In-sufficient Balance and your withdraw power is Rs.5400
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 45
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w', -


1500 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w', -1500 )
*
ERROR at line 1:
ORA-20504: Min. Trans. Amt. Rs.1/-
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 17
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

to check No.of Withdraws :


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

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600
3 sbi1 sbi2 01-NOV-23 at 1500
4 sbi1 01-NOV-23 w 100
5 sbi1 01-NOV-23 w 100
6 sbi1 01-NOV-23 w 120
7 sbi1 01-NOV-23 w 120
8 sbi1 01-NOV-23 w 120
9 sbi1 01-NOV-23 w 120
9 rows selected.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
4720
sbi2 KING HYD 9000994007 31-OCT-23 S
3000

COMPOSITE DATATYPES :
---------------------

-> It is also called as USER-DEFINED DATATYPES

ARRAY ->

x[1] = 10;
x[2] = 20;
x[3] = 30;
.
.
x[10]= 100;

x number;

x=100;
x=200;

N[1]=SMITH
N[2]=ALLEN
N[]
.
.
N[14]=MILLER

P[1]=900
P[2]=1700
P[]
.
.
P[14]=1400

DECLARE
TYPE NAMES IS TABLE OF EMP.ENAME%TYPE INDEX BY BINARY_INTEGER;
TYPE PAYS IS TABLE OF EMP.SAL%TYPE INDEX BY BINARY_INTEGER;

-- N, P are table type variables

N NAMES;
P PAYS;
CNT NUMBER := 1;
BEGIN
-- FILLING N,P ARRAY ELEMENTS

FOR I IN ( SELECT ENAME, SAL FROM EMP )


LOOP
N(CNT) := I.ENAME;
P(CNT) := I.SAL;
CNT := CNT + 1; -- 3
END LOOP;

-- DISPLAYING N,P ARRAY ELEMENTS

FOR K IN N.FIRST..N.LAST -- 1..14


LOOP
DBMS_OUTPUT.PUT_LINE( N(K)||'............'||P(K));
END LOOP;
END;
/

SMITH............900
ALLEN............1700
WARD............1350
JONES............3075
MARTIN............1350
BLAKE............2950
CLARK............2550
HEMANTH............3100
KING............5100
TURNER............1600
ADAMS............1200
JAMES............1050
FORD............3100
MILLER............1400

PL/SQL procedure successfully completed.

i.ename=ALLEN
i.sal=1700

PROCEDURE returns A PL/SQL TABLE :


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

-- write a stored procedure to return all JOBs from given deptno.

Package specification :
***********************

Create or replace package JOB_PACK


Is
TYPE Jobs_type is table of emp.job%type INDEX BY BINARY_INTEGER; --
public declaration
end Job_Pack;
/

Package created.

Procedure :
-----------

Create or replace procedure emp_jobs( p_deptno In emp.deptno%type,


p_jobs Out job_pack.jobs_type --
p_jobs is the arrary and returns multiple jobs
)
is
Begin
Select job Bulk collect into p_jobs from emp where deptno=p_deptno;
End emp_jobs;
/

calling procedure :
-------------------

declare
v_jobs job_pack.jobs_type;
Begin
emp_jobs(&deptno, v_jobs); -- calling procedure and v_jobs
contains given deptno. jobs
for i in v_jobs.first..v_jobs.last -- 1..3
loop
dbms_output.put_line( v_jobs(i ) );
end loop;
end;
/

MANAGER
PRESIDENT
CLERK

PL/SQL procedure successfully completed.

Enter value for deptno: 20


CLERK
MANAGER
ANALYST
CLERK
ANALYST

PL/SQL procedure successfully completed.

SQL> /
Enter value for deptno: 30
SALESMAN
SALESMAN
SALESMAN
MANAGER
SALESMAN
CLERK

PL/SQL procedure successfully completed.


LAG FUNCTION :
-------------

SQL> SELECT empno,


ename,
job,
sal,
LAG(sal, 1, 0) OVER (ORDER BY sal) AS sal_prev,
sal - LAG(sal, 1, 0) OVER (ORDER BY sal) AS sal_diff
FROM emp;

EMPNO ENAME JOB SAL SAL_PREV SAL_DIFF


------ ---------- --------- ------ -------- --------
7369 SMITH CLERK 900 0 900
7900 JAMES CLERK 1050 900 150
7876 ADAMS CLERK 1200 1050 150
7521 WARD SALESMAN 1350 1200 150
7654 MARTIN SALESMAN 1350 1350 0
7934 MILLER CLERK 1400 1350 50
7844 TURNER SALESMAN 1600 1400 200
7499 ALLEN SALESMAN 1700 1600 100
7782 CLARK MANAGER 2550 1700 850
7698 BLAKE MANAGER 2950 2550 400
7566 JONES MANAGER 3075 2950 125
7788 HEMANTH ANALYST 3100 3075 25
7902 FORD ANALYST 3100 3100 0
7839 KING PRESIDENT 5100 3100 2000

14 rows selected.

LEAD :
*******

SQL> SELECT empno,


ename,
job,
sal,
LEAD(sal, 1, 0) OVER (ORDER BY sal) AS sal_next,
LEAD(sal, 1, 0) OVER (ORDER BY sal) - sal AS sal_diff
FROM emp;

EMPNO ENAME JOB SAL SAL_NEXT SAL_DIFF


------ ---------- --------- ------ -------- --------
7369 SMITH CLERK 900 1050 150
7900 JAMES CLERK 1050 1200 150
7876 ADAMS CLERK 1200 1350 150
7521 WARD SALESMAN 1350 1350 0
7654 MARTIN SALESMAN 1350 1400 50
7934 MILLER CLERK 1400 1600 200
7844 TURNER SALESMAN 1600 1700 100
7499 ALLEN SALESMAN 1700 2550 850
7782 CLARK MANAGER 2550 2950 400
7698 BLAKE MANAGER 2950 3075 125
7566 JONES MANAGER 3075 3100 25
7788 HEMANTH ANALYST 3100 3100 0
7902 FORD ANALYST 3100 5100 2000
7839 KING PRESIDENT 5100 0 -5100

14 rows selected.

SQL> SELECT deptno,


empno,
ename,
job,
sal,
LEAD(sal, 1, 0) OVER (PARTITION BY deptno ORDER BY sal) AS
sal_next
FROM emp;

DEPTNO EMPNO ENAME JOB SAL SAL_NEXT


------ ------ ---------- --------- ------ --------
10 7934 MILLER CLERK 1400 2550
10 7782 CLARK MANAGER 2550 5100
10 7839 KING PRESIDENT 5100 0

20 7369 SMITH CLERK 900 1200


20 7876 ADAMS CLERK 1200 3075
20 7566 JONES MANAGER 3075 3100
20 7788 HEMANTH ANALYST 3100 3100
20 7902 FORD ANALYST 3100 0

FIRST & LAST FUNCTIONS :


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

SQL> SELECT empno,


deptno,
sal,
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION
BY deptno) AS lowest,
MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION
BY deptno) AS highest
FROM emp
ORDER BY deptno, sal;

EMPNO DEPTNO SAL LOWEST HIGHEST


------ ------ ------ ------ -------
7934 10 1400 1400 5100
7782 10 2550 1400 5100
7839 10 5100 1400 5100

7369 20 900 900 3100


7876 20 1200 900 3100
7566 20 3075 900 3100
7788 20 3100 900 3100
7902 20 3100 900 3100

7900 30 1050 1050 2950


7654 30 1350 1050 2950
7521 30 1350 1050 2950
7844 30 1600 1050 2950
7499 30 1700 1050 2950
7698 30 2950 1050 2950

14 rows selected.
30 7900 JAMES CLERK 1050 1350
30 7654 MARTIN SALESMAN 1350 1350
30 7521 WARD SALESMAN 1350 1600
30 7844 TURNER SALESMAN 1600 1700
30 7499 ALLEN SALESMAN 1700 2950
30 7698 BLAKE MANAGER 2950 0

14 rows selected.

SQL> SELECT empno,


deptno,
sal,
MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION
BY deptno) AS lowest,
MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION
BY deptno) AS highest
FROM emp
ORDER BY deptno, sal;

EMPNO DEPTNO SAL LOWEST HIGHEST


------ ------ ------ ------ -------
7934 10 1400 1400 5100
7782 10 2550 1400 5100
7839 10 5100 1400 5100

7369 20 900 900 3100


7876 20 1200 900 3100
7566 20 3075 900 3100
7788 20 3100 900 3100
7902 20 3100 900 3100

7900 30 1050 1050 2950


7654 30 1350 1050 2950
7521 30 1350 1050 2950
7844 30 1600 1050 2950
7499 30 1700 1050 2950
7698 30 2950 1050 2950

14 rows selected.

SQL> select empno, sal, dense_rank() over( order by sal desc ) as drnk
from emp;

EMPNO SAL DRNK


------ ------ ------
7839 5100 1
7902 3100 2
7788 3100 2
7566 3075 3
7698 2950 4
7782 2550 5
7499 1700 6
7844 1600 7
7934 1400 8
7521 1350 9
7654 1350 9
7876 1200 10
7900 1050 11
7369 900 12

14 rows selected.

PARTITIONS & LOCKS :


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

PARTITIONS

-> Supports to divide huge tables into logical partitions to improve


performance while retrieving / manipulating data.

Partitioning Methods

There are several partitioning methods offered by Oracle Database:

- Range partitioning
- List partitioning

Range Partitioning

Use range partitioning to map rows to partitions based on ranges of


column values.

SQL>
Create table emp345
(empno number(3) primary key,
ename varchar2(30),
sal number(8,2),
deptno number(2))
Partition by range (deptno)
(Partition p1 values less than (10),
Partition p2 values less than (20),
Partition p3 values less than (30),
Partition p4 values less than (40)
) ;

Inserting data into partition Table :


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

SQL> Insert into Emp345 values(11,'king',5000,15);

SQL> Insert into Emp345 values(22,'scott',3000,5);

SQL> Insert into Emp345 values(33,'jones',2500,35);

SQL> Insert into Emp345 values(44,'allen',1500,25);

SQL> Select *from emp345;

EMPNO
----------
22
11
44
33

List Partitioning

Use list partitioning when you require explicit control over how rows map
to partitions. You can specify a list of discrete values for the
partitioning column in the description for each partition.

SQL> CREATE TABLE Dept_part


( deptno number(2),
deptname varchar2(20),
state varchar2(2)
)
PARTITION BY LIST (state)
( PARTITION q1 VALUES ( 'OR', 'WB' ),
PARTITION q2 VALUES ( 'AP', 'UP', 'MP' ) ,
PARTITION q3 VALUES ( 'NG', 'TN', 'KA' ),
PARTITION q4 VALUES ( 'RJ', 'TG' )
) ;

Insert Into Dept_Part Values ( 10,'Acc','AP');


Insert Into Dept_Part Values ( 20,'RES','OR');
Insert Into Dept_Part Values ( 30,'FIN','TG');
Insert Into Dept_Part Values ( 40,'ADMIN','TN');

SELECT * FROM DEPT_PART ;

SQL> select partition_name from dba_tab_subpartitions where


table_name='EMP345'

Adding a Partition to a Partitioned Table


alter table emp345 add partition p5 values less than (50);

Truncating Partitions
alter table emp345 truncate partition p5;

Dropping a Table Partition


Alter table emp345 drop partition p5;

Merging Partitions

ALTER TABLE emp345 MERGE PARTITIONS


p1 , p2 into PARTITION p6 ;

Renaming a Table Partition

Alter Table Emp345 Rename PARTITION p4 to p45;

LOCKS

Lock means : U can do the update transaction at one location and the
another person do the same transaction at another location it can occurs
the dead lock situation.
1. Implicit Locks:

? U & another person do the same transaction at the same time dead
locks occurs at that time who enter the Transaction first that will
decided by the implicit Locks. Whose person can open the table that
person will do that transaction.

2. Explicit Locks:

? U can do some Transaction these Transactions are completed to allow


the other person that is explicit Lock.
? U can provide our own manipulation per particular time given after
the time finish another person comes.
? How to Lock release in Explicit Locks used by commit/rollback.

Type of locks

1. row level locks


2. table locks

--> Row Level Locks:


This lock is used to lock either a single or group of
records, for the purpose of updations. A Row Level Lock is implemented
with in a select query using "for update of " clause.

Ex: Select * from emp where empno=7788 for update of comm,sal;

note: another user cannot manipulate comm&sal of 7788,for the rest of the
numbers & entities he can do manipulation

Ex: Select * from emp for update of comm, sal;

Note: another user cannot manipulate comm&sal all the numbers, for the
rest of the entities he can do manipulation

Ex: Select * from EMP for update;(to lock the table)

note: another user cannot manipulate all the entities of the table

Note: only manipulations r not allowed but he can retrieve values


(select)of the table

II. Table Level Locks :


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

-> To Lock the Entire Table

Ex: LOCK TABLE EMP SHAREMODE;

SQL * LOADER :
--------------

-> SQL *LOADER is used to copies Flat Files information to Oracle DBs

-> Once ORACLE installed, SQL LOADER automatically installed.


Ex:-

-- Example for copying NOTEPAD file data into Oracle Database Tables

notepad :
----------
1,king,5000,10
2,scott,6000,20
3,jones,4000,10
4,smith,4500,30
5,james,2500,20
6,allen,1800,10
.
.
100000,.....

Step1 :
-------

-- create a new notepad file in 'D' drive with Name as D:\EMP.TXT

D:\EMP.TXT
-----------
1,king,5000,10
2,scott,6000,20
3,jones,4000,10
4,smith,4500,30
5,james,2500,20
6,allen,1800,10

Step2 :
--------

-- Connect to Ora8pm user and create a new table with 4 columns like
empno, ename, sal & deptno

username: ora8pm
password: tiger

SQL> create table emp_db(empno number(4), ename varchar2(10), sal


number(8,2), deptno number(2));

Table created.

step 3:
-------

-- Create a new notepad file in 'D' drive with name as 'D:\MYCTL.CTL'

'D:\MYCTL.CTL'
--------------

LOAD DATA
INFILE "D:\EMP.TXT"
INSERT INTO TABLE EMP_DB
FIELDS TERMINATED BY ','
(EMPNO, ENAME,SAL,DEPTNO)

Step 4:
--------

-- Execute the script

** goto command prompt

C:\Users\sarmamicrosoft> sqlldr ora8pm/tiger

control = d:\myctl.ctl

SQL*Loader: Release 11.2.0.2.0 - Production on Thu Nov 9 20:31:03 2023

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights
reserved.

Commit point reached - logical record count 5


Commit point reached - logical record count 6

step5 :
--------

-- check the emp_db table information in 'ORA8PM' user

SQL> select * from emp_db;

EMPNO ENAME SAL DEPTNO


---------- ---------- ---------- ----------
1 king 5000 10
2 scott 6000 20
3 jones 4000 10
4 smith 4500 30
5 james 2500 20
6 allen 1800 10

6 rows selected.

Example for copying EXCEL SHEET file data into Oracle Database Tables:
**********************************************************************

Step1 :
-------

-- create a new excel sheet in 'D' drive with Name as D:\EMP.CSV

NOTE: excel sheet should be save with '.CSV' extension

D:\EMP.CSV
-----------
1,king,5000,10
2,scott,6000,20
3,jones,4000,10
4,smith,4500,30
5,james,2500,20
6,allen,1800,10

Step2 :
--------

-- Connect to Ora8pm user and create a new table with 4 columns like
empno, ename, sal & deptno

username: ora8pm
password: tiger

SQL> create table emp_db(empno number(4), ename varchar2(10), sal


number(8,2), deptno number(2));

Table created.

step 3:
-------

-- Create a new notepad file in 'D' drive with name as 'D:\MYCTL.CTL'

'D:\MYCTL.CTL'
--------------

LOAD DATA
INFILE "D:\EMP.CSV"
INSERT INTO TABLE EMP_DB
FIELDS TERMINATED BY ','
(EMPNO, ENAME,SAL,DEPTNO)

Step 4:
--------

-- Execute the script

** goto command prompt

C:\Users\sarmamicrosoft> sqlldr ora8pm/tiger

control = d:\myctl.ctl

SQL*Loader: Release 11.2.0.2.0 - Production on Thu Nov 9 20:31:03 2023

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights
reserved.

Commit point reached - logical record count 5


Commit point reached - logical record count 6
step5 :
--------

-- check the emp_db table information in 'ORA8PM' user

SQL> select * from emp_db;

EMPNO ENAME SAL DEPTNO


---------- ---------- ---------- ----------
1 king 5000 10
2 scott 6000 20
3 jones 4000 10
4 smith 4500 30
5 james 2500 20
6 allen 1800 10

6 rows selected.

TO APPEND Data into DB TABLES :


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

Step1 :
-------

-- create a new excel sheet in 'D' drive with Name as D:\EMP.txt

NOTE: excel sheet should be save with '.CSV' extension

D:\EMP.txt
-----------
7,blake,6000,30
8,clark,3000,10
9,ford,4000,10

step 2:
-------

-- Create a new notepad file in 'D' drive with name as 'D:\MYCTL.CTL'

'D:\MYCTL.CTL'
--------------

LOAD DATA
INFILE "D:\EMP.CSV"
APPEND INTO TABLE EMP_DB
FIELDS TERMINATED BY ','
(EMPNO, ENAME,SAL,DEPTNO)

Step 4:
--------
-- Execute the script

** goto command prompt

C:\Users\sarmamicrosoft> sqlldr ora8pm/tiger

control = d:\myctl.ctl

SQL*Loader: Release 11.2.0.2.0 - Production on Thu Nov 9 20:31:03 2023

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights
reserved.

Commit point reached - logical record count 3


Commit point reached - logical record count 3

step5 :
--------

-- check the emp_db table information in 'ORA8PM' user

SQL> select * from emp_db;

EMPNO ENAME SAL DEPTNO


---------- ---------- ---------- ----------
1 king 5000 10
2 scott 6000 20
3 jones 4000 10
4 smith 4500 30
5 james 2500 20
6 allen 1800 10
7 blake 6000 30
8 clark 3000 10
9 ford 4000 10

6 rows selected.

EXPORT & IMPORT :


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

-> EXPORT & IMPORTS are copying data from source database to
destination database

-> It is done by DBA

EXPORT :
--------

-> This command is used to Exporting/copying Data from Source Database


Into O.S file

EX:-

Step1 : goto command prompt

C:\Users\sarmamicrosoft>exp
Export: Release 11.2.0.2.0 - Production on Fri Nov 10 20:12:52 2023

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights
reserved.

Username: ora8pm/tiger

Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 -


64bit Production
Enter array fetch buffer size: 4096 >

Export file: EXPDAT.DMP > d:\ora8pm.dmp

(1)E(ntire database), (2)U(sers), or (3)T(ables): (2)U > u

Export grants (yes/no): yes > n

Export table data (yes/no): yes > y

Compress extents (yes/no): yes > y

Export done in WE8MSWIN1252 character set and AL16UTF16 NCHAR character


set
server uses AL32UTF8 character set (possible charset conversion)
Note: grants on tables/views/sequences/roles will not be exported

About to export specified users ...


User to be exported: (RETURN to quit) > ora8pm

User to be exported: (RETURN to quit) >

. exporting pre-schema procedural objects and actions


. exporting foreign function library names for user ORA8PM
. exporting PUBLIC type synonyms
. exporting private type synonyms
. exporting object type definitions for user ORA8PM
About to export ORA8PM's objects ...
. exporting database links
. exporting sequence numbers
. exporting cluster definitions
. about to export ORA8PM's tables via Conventional Path ...
. . exporting table BANK_MAS 2 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table BANK_MASS 0 rows
exported
. . exporting table BANK_TRANS 9 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table BONUS 0 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table DEPT 4 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table DUMMY 1 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table EMP 14 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table EMPLOY_INCR 13 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table EMP_BACKUP 1 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table EMP_DB 6 rows
exported
. . exporting table EMP_STATUS 0 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table HOLIDAY 3 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table LOGIN_DETAILS 15 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table SALGRADE 5 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table STD_DB 1 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table STD_MARKS 1 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table TG 3 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table TV 2 rows
exported
EXP-00091: Exporting questionable statistics.
. . exporting table USER_DETAILS 2 rows
exported
EXP-00091: Exporting questionable statistics.
. exporting synonyms
. exporting views
. exporting stored procedures
. exporting operators
. exporting referential integrity constraints
. exporting triggers
. exporting indextypes
. exporting bitmap, functional and extensible indexes
. exporting posttables actions
. exporting materialized views
. exporting snapshot logs
. exporting job queues
. exporting refresh groups and children
. exporting dimensions
. exporting post-schema procedural objects and actions
. exporting statistics
Export terminated successfully with warnings.

C:\Users\sarmamicrosoft>

'\' is not recognized as an internal or external command,


operable program or batch file.
C:\Users\sarmamicrosoft>

step2 :
-------

-> In client system create a NEW USER with DBA permissions

connect :
---------
username : system
password : server

SQL> create user client_user identified by tiger;

User created.

SQL> grant dba to client_user;

Grant succeeded.

step 3:
-------

IMPORT :
--------

-> It is used to copies DUMP file information into ORACLE DATABASE

-> goto command prompt

C:\Users\sarmamicrosoft>IMP

Import: Release 11.2.0.2.0 - Production on Fri Nov 10 20:39:23 2023

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights
reserved.

Username: client_user/tiger

Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 -


64bit Production

Import data only (yes/no): no > n

Import file: EXPDAT.DMP > D:\ORA8PM.DMP

Enter insert buffer size (minimum is 8192) 30720>

Export file created by EXPORT:V11.02.00 via conventional path

Warning: the objects were exported by ORA8PM, not by you

import done in WE8MSWIN1252 character set and AL16UTF16 NCHAR character


set
import server uses AL32UTF8 character set (possible charset conversion)
List contents of import file only (yes/no): no > N
Ignore create error due to object existence (yes/no): no > Y

Import grants (yes/no): yes > Y

Import table data (yes/no): yes > Y

Import entire export file (yes/no): no > Y

. importing ORA8PM's objects into CLIENT_USER


. . importing table "BANK_MAS" 2 rows
imported
. . importing table "BANK_MASS" 0 rows
imported
. . importing table "BANK_TRANS" 9 rows
imported
. . importing table "BONUS" 0 rows
imported
. . importing table "DEPT" 4 rows
imported
. . importing table "DUMMY" 1 rows
imported
. . importing table "EMP" 14 rows
imported
. . importing table "EMPLOY_INCR" 13 rows
imported
. . importing table "EMP_BACKUP" 1 rows
imported
. . importing table "EMP_DB" 6 rows
imported
. . importing table "EMP_STATUS" 0 rows
imported
. . importing table "HOLIDAY" 3 rows
imported
. . importing table "LOGIN_DETAILS" 15 rows
imported
. . importing table "SALGRADE" 5 rows
imported
. . importing table "STD_DB" 1 rows
imported
. . importing table "STD_MARKS" 1 rows
imported
. . importing table "TG" 3 rows
imported
. . importing table "TV" 2 rows
imported
. . importing table "USER_DETAILS" 2 rows
imported
About to enable constraints...
Import terminated successfully without warnings.

C:\Users\sarmamicrosoft>

Step 4:
-------

-> connect to CLIENT_USER user and execute below query

ex:-
SQL> SELECT OBJECT_NAME FROM USER_OBJECTS;

Example Program :
-----------------

--> Create a Package program to develop following modules

i. Create a New Account (proc)

ii. View Account Details (proc)

iii. Deposit Amt. (proc)

iv. Withdraw Amt. (proc)

v. Money Transfer using Accnos (proc)

vi. Check Balance (func)

vii. Mini Statement (proc)

viii. Account Statement (proc)

ix. Delete Account (proc)

i. Create a New Account

Validations :
-------------

-> Account No. should be generate automatically

ex: sbi1, sbi2,....

-> mobile no should be accepts 10 digits only and it should be unique.

-> opening date is today date

-> account type should be accepts 's' or 'c'

-> Min. Opening Account Balance Rs.1000/-

ii. ii. View Account Details :


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

-> to view account details by using Accno.

vi. Check Balance :


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

-> to check the balance by using ACNO / MOBILENO

Table Creation :
----------------
Bank_Mas :
----------

Create Table bank_mas( Acno Varchar2(10), Cname varchar2(10),


Addr Varchar2(20), Mobileno Number(10),
odate date, acc_type char(1),
Bal Number(8,2)
);

Bank_Trans :
------------

Create Table Bank_Trans( Tno number(10), sacno varchar2(10),


dacno varchar2(10), tdate date,
ttype char(2), tamt number(8,2)
);

Sequences :
-----------

-> Sequences are used to generate ACNOs & TNOs

Acnos :
-------

Create sequence acno_seq


start with 1
increment by 1;

PACKAGE SPECIFICATION :
-----------------------

Create or replace package BANK_PACK


is

-- Proc. spec for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
);

-- Proc spec for to view account details

Procedure view_acc( p_acno bank_mas.acno%type );

-- Proc spec for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type );

-- Proc spec for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


);

-- Proc spec for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
);

-- Function spec. for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number;

-- Function spec. for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number;

-- Procedure spec. for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type );

-- Procedure spec. for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date );

-- Procedure spec. for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type);

End BANK_PACK;
/

PACKAGE BODY :
--------------

Create or replace package Body BANK_PACK


is

-- Proc. body for to open a new account


Procedure new_acc( p_cname bank_mas.cname%type,
p_addr bank_mas.addr%type,
p_mobileno bank_mas.mobileno%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type
)
is
mcnt number;
Begin
if length( p_mobileno) !=10 then
raise_application_error(-20001, 'Invalid Mobileno No.!!!!');
end if;
select count(*) into mcnt from bank_mas where mobileno = p_mobileno;
if mcnt=1 then
raise_application_error(-20002, 'Mobileno Already Registered.');
end if;
if lower( p_acc_type ) not in ( 's', 'c' ) then
raise_application_error(-20003, 'Invalid Accoun type....');
end if;
if p_bal <1000 then
raise_application_error(-20004, 'Min. A/c Opening Balance
Rs.1000/-.');
end if;
Insert Into bank_mas values ( 'sbi'||(acno_seq.nextval), p_cname,
p_addr, p_mobileno, sysdate, p_acc_type, p_bal);
dbms_output.put_line('Account Created Successfully.');
End New_Acc;

-- Proc body for to view account details

Procedure view_acc( p_acno bank_mas.acno%type )


is
bm bank_mas%rowtype;
Begin
select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('**** ACCOUNT DETAILS ARE ****');
dbms_output.put_line('Account No. ' || bm.acno );
dbms_output.put_line('Customer Name ' || bm.cname );
dbms_output.put_line('Account Address ' || bm.addr );
dbms_output.put_line('Account Mobileno ' || bm.mobileno );
dbms_output.put_line('Account Opening date ' || bm.odate );
dbms_output.put_line('Account type ' || bm.acc_type );
dbms_output.put_line('Account Bal ' || bm.bal );
dbms_output.put_line('**** END OF THE RECORD ****');
Exception
when no_data_found then
raise_application_error(-20005, 'Invalid Account No.');
End View_Acc;

-- Proc body for to deposit Amt.

Procedure Credit( p_acno bank_mas.acno%type, p_tamt


bank_trans.tamt%type )
is
Begin
Update bank_mas set Bal = Bal + p_tamt where acno = p_acno;
dbms_output.put_line('amt. deposited.');
End Credit;

-- Proc body for to withdraw Amt.

Procedure Debit( p_acno bank_mas.acno%type, p_tamt bank_trans.tamt%type


)
is
Begin
Update bank_mas set Bal = Bal - p_tamt where acno = p_acno;
dbms_output.put_line('amt. withdraw successfully');
End Debit;

-- Proc body for to transfer amt. by using account nos.

Procedure Acc_trans( p_Sacno bank_trans.sacno%type,


p_Dacno bank_trans.dacno%type,
p_Tamt Bank_trans.tamt%type
)
is
Begin
debit( p_Sacno, p_tamt );
credit( p_dacno, p_tamt );
dbms_output.put_line('Amt. Transfer successfully.');
End Acc_trans;

-- Function body for to check account balance by using ACNO

Function chk_bal( p_acno bank_mas.acno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return ( v_bal );
End Chk_Bal;

-- Function body for to check account balance by using MOBILENO

Function chk_bal( p_mobileno bank_mas.mobileno%type ) return number


is
v_bal bank_mas.bal%type;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return ( v_bal );
End Chk_Bal;

-- Procedure Body for to generate mini statement

Procedure mini_stat( p_sacno bank_trans.sacno%type )


is
cursor mini_cur is Select * from ( select sacno, tdate, ttype, tamt
from bank_trans
where sacno = p_sacno
order by tdate desc )
where rownum <=5 order
by tdate;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('**** MINI STATEMENT ****');
Loop
fetch mini_cur into bt;
exit when mini_cur%notfound;
dbms_output.put_line( bt.sacno||' '||bt.tdate||' '||bt.ttype||'
'||bt.tamt );
End Loop;
dbms_output.put_line('************************');
close mini_cur;
End mini_stat;

-- Procedure Body for to generate account statement

Procedure Acc_stat( p_sacno bank_trans.sacno%type, p_sdate date,


p_edate date )
is
cursor acc_cur is select * from Bank_trans where trunc(Tdate) Between
trunc(p_sdate) and trunc(p_edate) and Sacno=P_sacno;
bt acc_cur%rowtype;
v_acno bank_mas.acno%type;
v_cname bank_mas.cname%type;
v_acc_type bank_mas.acc_type%type;
v_bal bank_mas.bal%type;
Begin
select acno, cname, acc_type, bal into v_acno, v_cname, v_acc_type,
v_bal
from bank_mas where acno =
p_sacno;
dbms_output.put_line('**** Customer Details ****');
dbms_output.put_line( 'A/c No. ' || v_acno);
dbms_output.put_line( 'Cust Name ' || v_cname);
dbms_output.put_line( 'A/c. Type ' || v_acc_type);
dbms_output.put_line( 'Balance ' || v_bal);
dbms_output.put_line('**************************');
dbms_output.put_line('****Account Statement****');
open acc_cur;
Loop
fetch acc_cur into bt;
exit when acc_cur%notfound;
dbms_output.put_line( bt.Sacno||' '||bt.Tdate||' '||bt.Ttype||'
'||bt.Tamt);
End Loop;
dbms_output.put_line('**************************');
close acc_cur;
End Acc_stat;

-- Procedure body for to delete account

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from bank_mas where acno = p_acno;
if sql%found then
commit;
dbms_output.put_line('Account Deleted Successfully.');
else
dbms_output.put_line('Record Not Found');
end if;
End del_Acc;

END BANK_PACK;
/

CALLING PACKAGE PROGRAMS :


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

i. To Open a New Account :


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

SQL> EXEC BANK_PACK.NEW_ACC('KING', 'HYD', 9000994005, 'S', 2500 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> EXEC BANK_PACK.NEW_ACC('SCOTT', 'SEC', 9000994006, 'C', 4000 );


Account Created Successfully.

PL/SQL procedure successfully completed.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

Invalid input :
---------------

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994006, 'C', 5000 ); END;

*
ERROR at line 1:
ORA-20002: Mobileno Already Registered.
ORA-06512: at "ORA8PM.BANK_PACK", line 19
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'X', 5000 ); END;

*
ERROR at line 1:
ORA-20003: Invalid Accoun type....
ORA-06512: at "ORA8PM.BANK_PACK", line 22
ORA-06512: at line 1

SQL> EXEC BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 );


BEGIN BANK_PACK.NEW_ACC('SMITH', 'HYD', 9000994007, 'S', 500 ); END;

*
ERROR at line 1:
ORA-20004: Min. A/c Opening Balance Rs.1000/-.
ORA-06512: at "ORA8PM.BANK_PACK", line 25
ORA-06512: at line 1

II. VIEW ACCOUNT DETAILS :


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

SQL> EXEC BANK_PACK.VIEW_ACC('sbi1');

**** ACCOUNT DETAILS ARE ****


Account No. sbi1
Customer Name KING
Account Address HYD
Account Mobileno 9000994005
Account Opening date 21-OCT-23
Account type S
Account Bal 2500
**** END OF THE RECORD ****

PL/SQL procedure successfully completed.

IV. CREDIT ( DEPOSTI AMT. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.CREDIT( 'sbi1', 1000 );


amt. deposited.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

IV. DEBIT ( Withdraw Amt. ) :


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

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
3500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> EXEC BANK_PACK.DEBIT( 'sbi1', 1500 );


amt. withdraw successfully

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000
V. CHECK BALANCE by using ACNO :
********************************

SQL> SELECT BANK_PACK.CHK_BAL('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
2000

CHECK BALANCE by using MOBILENO :


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

SQL> SELECT BANK_PACK.CHK_BAL(9000994005) from dual;

BANK_PACK.CHK_BAL(9000994005)
-----------------------------
2000

VI. MINI STATEMENT :


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

SQL> EXEC BANK_PACK.MINI_STAT( 'sbi1' );

**** MINI STATEMENT ****


sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
************************

PL/SQL procedure successfully completed.

VII. ACCOUNT STATEMENT :


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

SQL> EXEC BANK_PACK.ACC_STAT( 'sbi1', '01-oct-2023', '21-oct-2023');

**** Customer Details ****


A/c No. sbi1
Cust Name KING
A/c. Type S
Balance 2000
**************************

****Account Statement****
sbi1 01-OCT-23 w 300
sbi1 06-OCT-23 w 500
sbi1 14-OCT-23 d 800
sbi1 20-OCT-23 w 300
sbi1 21-OCT-23 w 600
**************************

PL/SQL procedure successfully completed.

VIII. AMT. transfer by using ACCNOs :


*************************************
SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
2000
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4000

SQL> exec bank_pack.acc_trans( 'sbi1', 'sbi2', 500 );


amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 KING HYD 9000994005 21-OCT-23 S
1500
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

IX. DELETE ACCOUNT :


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

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Account Deleted Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi2 SCOTT SEC 9000994006 21-OCT-23 C
4500

SQL> EXEC BANK_PACK.DEL_ACC('sbi1');


Record Not Found

PL/SQL procedure successfully completed.

sample insertions :
-------------------
insert into bank_trans values ( 1, 'sbi1', null, '16-sep-2023', 'd', 1000
);
insert into bank_trans values ( 2, 'sbi1', null, '23-sep-2023', 'w', 200
);
insert into bank_trans values ( 4, 'sbi2', null, '29-sep-2023', 'd', 500
);
insert into bank_trans values ( 5, 'sbi1', null, '01-oct-2023', 'w', 300
);
insert into bank_trans values ( 6, 'sbi1', null, '06-oct-2023', 'w', 500
);
insert into bank_trans values ( 7, 'sbi2', null, '09-oct-2023', 'w', 100
);
insert into bank_trans values ( 8, 'sbi1', null, '14-oct-2023', 'd', 800
);
insert into bank_trans values ( 9, 'sbi1', null, '20-oct-2023', 'w', 300
);
insert into bank_trans values ( 10, 'sbi1', null, '21-oct-2023', 'w', 600
);

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE T TAMT


---------- ---------- ---------- --------- - ----------
1 sbi1 16-SEP-23 d 1000
2 sbi1 23-SEP-23 w 200
4 sbi2 29-SEP-23 d 500
5 sbi1 01-OCT-23 w 300
6 sbi1 06-OCT-23 w 500
7 sbi2 09-OCT-23 w 100
8 sbi1 14-OCT-23 d 800
9 sbi1 20-OCT-23 w 300
10 sbi1 21-OCT-23 w 600

9 rows selected.

TRIGGERS :
----------

-> Trigger is one of the Named Block program and used to execute
automatically

-> Triggers are executes automatically based on the EVENT

-> In Oracle DB Trigger programs are executed whenever DML operations


are performed

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict USER-DEFINED Conditions and Business


Rules

-> All created trigger names are stored in USER_OBJECTS / USER_TRIGGERS

-> All created trigger bodies are stored in USER_SOURCE table

Trigger Parts :
---------------

i. Trigger Event :- It indicates when to activate(execute) the trigger


Oracle supports some trigger events...

a. before insert b. before update c.


before delete

d. after insert e. after update f.


after delete

ii. Trigger Type :- It indicates, type of the trigger

Oracle supports two types of triggers

i. row level triggers :- Trigger body executes


each and every row

ii. statement level triggers :- Trigger body


executes only once on entire table

iii. Trigger restriction :- Used to stop automatic execution of code

iv. Trigger Body :- A set of PL/SQL statements

Trigger syntax :-
-----------------

Create or replace Trigger <trigger_name>


Before/After Insert or Update or Delete -- i
[of Columns] ON <table_name>
[for each row] -- ii
[when <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** to perform any DML operations on SQL prompt first data will be stored
ROLLBACK segment

DEPT -- step3
-----
DEPTNO DNAME LOC
50 MATHS HYD

rollback segment : -- step2


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

:deptno=50 :dname=maths :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1


** in rollback segment column values are stored in preceeding ':'
operator

ex: :deptno, :dname, :loc, etc.,

** Triggers are supports two types of ACCESS Specifiers

i. new ii. old

** these are placed in preceeding rollback segment column names based on


trigger event

ex: :new.deptno, :old.deptno, etc.,

before insert
before update :NEW.
before delete
after insert

after insert
after delete :OLD.
after update

Example :-

-- write a trigger program while inserting data to chaange DEPT.NAME


into capital letters

DEPT -- step4
-----
DEPTNO DNAME LOC
50 MATHS hyd

rollback segment : -- step2


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

:deptno=50 :dname=MATHS :loc=hyd

sql> INSERT INTO DEPT VALUES( 50, 'maths', 'hyd' ); -- step1

Triger program :
----------------

Create or replace trigger dept_trig -- STEP 3


Before Insert On dept
for each row
Begin
:new.dname := upper(:new.dname);
End;
/
Trigger created.

SQL> insert into dept values ( 50, 'maths', 'hyd' );

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS hyd

Example2 :-

-- Write a trigger program to raise error if updating salary is


lessthan existing salary

Create or replace trigger emp_upd_trig


Before Update on emp
for each row
begin
if :New.sal < :old.sal then
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary.');
end if;
end;
/

rollback segment :
-----------------
:old.empno=7902, :old.ename='ford'... :old.sal = 4650,...

:new.sal = 4000, :new.empno=7902

testing:-
*********

SQL> update emp set sal=4000 where empno=7902;


update emp set sal=4000 where empno=7902
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary.
ORA-06512: at "ORA8PM.EMP_UPD_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA8PM.EMP_UPD_TRIG'

SQL> update emp set sal=4700 where empno=7902;

1 row updated.

SQL> select * from emp;


EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 23-SEP-23 4700 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

13 rows selected.

example 3 :
-----------

-- write a trigger program to take employee records backup

** create a employee backup table with the same structure of EMP table
without data

SQL> create table emp_backup as select * from emp where 1=2;

Table created.

SQL> desc emp_backup;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
EMPNO NOT NULL NUMBER(4)
ENAME
VARCHAR2(10)
JOB
VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL
NUMBER(7,2)
COMM
NUMBER(7,2)
DEPTNO NUMBER(2)

Trigger program :
-----------------

Create or replace trigger emp_del_trig


AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
Insert into emp_backup values ( :old.empno, :old.ename, :old.job,
:old.mgr,:old.hiredate, :old.sal,
:old.comm, :old.deptno);
dbms_output.put_line('Backup taken successfully.');

END;
/

ROLLBACK SEGMENT :-
-------------------

:old.empno=7902, :old.ename='ford',,,, :old.deptno=20

Testing :-

SQL> delete from emp where empno=7902;


Backup taken successfully.

1 row deleted.

SQL> select * from emp_backup;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7902 FORD ANALYST 7566 23-SEP-23 4700 20

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 21-OCT-23 1350 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 13-OCT-23 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 4612.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7839 KING PRESIDENT 17-NOV-81 9000 10
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1800 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10

12 rows selected.

-- write a trigger program to generate employee no. automatically

sequence :
----------

create sequence my_seq


start with 1
increment by 1;

table creation:
---------------
create table emp_db( eno number(2), ename varchar2(10));

Trigger :-
-----------

Create or replace trigger emp_db_ins_trig


Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version

:new.eno := my_seq.nextval; -- oracle 11g feature


end;
/

rollback segment :-
*******************

:new.eno=1, :new.ename='king'

Testing:-

SQL> select * from emp_db;

no rows selected

SQL> Insert into emp_db(ename) values ( 'king' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'scott' );

1 row created.

SQL> Insert into emp_db(ename) values ( 'james' );

1 row created.

SQL> select * from emp_db;

ENO ENAME
------ ----------
1 king
2 scott
3 james

example 6:-
-----------

-> write a trigger program to peform DML operations on EMP table and
Transaction status should be
EMPLOYEE_STATUS table

Table creation :-
-----------------
SQL> Create table emp_status ( eno number(4), sdate date, status
varchar2(40));

Table created.

Trigger program :
----------------

Create or replace trigger EMP_DML_TRIG


After INSERT or UPDATE or DELETE
on EMP
For each row
Begin
if INSERTING then

Insert into emp_status values( :new.empno, sysdate, 'new employee


recruited.');
elsif UPDATING then

Insert into emp_status values( :new.empno, sysdate, 'employee record


updated.');

elsif DELETING then

Insert into emp_status values( :old.empno, sysdate, 'Employee


removed from the ORG.');

end if;

End;
/

II. STATEMENT LEVEL TRIGGERS :


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

-> Trigger program executed only once on entire table

-> In Statement Level triggers, Trigger Access specifiers( new & old )
not supported

ex:-

-- write a trigger program to restrict DML operations on EMP table


based on the following conditions.

i. Office timings are 10:00am to 5pm

ii. Weekends holidays

iii. On Public Holidays also holiday

Create a Holiday table with HOliday Dates :


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

Create table Holiday( Hdate date );

Insert into holiday values( '26-jan-23' );


Insert into holiday values( '15-aug-23' );
Insert into holiday values( '25-dec-23' );

SQL> select * from holiday;

HDATE
---------
26-JAN-23
15-AUG-23
25-DEC-23

Trigger program :
-----------------

Create or replace trigger holiday_trig


Before Insert or update or Delete
on Emp
Declare
cnt number;
Begin
if to_char(sysdate, 'hh24' ) not between 10 and 16 then
raise_application_error(-20001, 'Off-timings, Trans. are not
allowed.');
end if;

if to_char( sysdate, 'dy' ) in ( 'sat','sun') then


raise_application_error(-20002, 'Week-ends, Trans. are not
allowed.');
end if;

select count(hdate) into cnt from holiday


where trunc(hdate)=trunc(sysdate);
if cnt = 1 then
raise_application_error(-20003, 'Today Public Holiday, Trans. are
Not Allowed.');
end if;
End;
/

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20001: Off-timings, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 5
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20002: Week-ends, Trans. are not allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 9
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 1000;


Update emp set sal = sal + 1000
*
ERROR at line 1:
ORA-20003: Today Public Holiday, Trans. are Not Allowed.
ORA-06512: at "ORA8PM.HOLIDAY_TRIG", line 15
ORA-04088: error during execution of trigger 'ORA8PM.HOLIDAY_TRIG'

SQL> Update emp set sal = sal + 100;

14 rows updated.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 900 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1700 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1350 500 30
7566 JONES MANAGER 7839 02-APR-81 3075 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1350 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2950 30
7782 CLARK MANAGER 7839 09-JUN-81 2550 10
7788 SCOTT ANALYST 7566 09-DEC-82 3100 20
7839 KING PRESIDENT 17-NOV-81 5100 10
7844 TURNER SALESMAN 7698 08-SEP-81 1600 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1200 20
7900 JAMES CLERK 7698 03-DEC-81 1050 30
7902 FORD ANALYST 7566 03-DEC-81 3100 20
7934 MILLER CLERK 7782 23-JAN-82 1400 10

14 rows selected.

** why we are usign TRUNCATE on SYSDATE

SQL> select 1 from dual where trunc(to_date('27-oct-23') ) =


trunc(sysdate);

1
------
1

SQL> select 1 from dual where '27-oct-23' = trunc(sysdate);

1
------
1
ex:-

-- write a trigger program to not allow transactions on BANK_MASTER


TABLE based on following conditions

i. Bank timings 10:00 to 2:30 and 3:00pm to 4:00pm

ii. every 2nd & 4th Saturday days holidays

iii. On Public Holidays also holidays

III. INSTEAD OF TRIGGERS :


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

-> Generally we can write triggers on DB TABLES. But, we can write


triggers on VIEWS also.

-> To write triggers on VIEWS the event is INSTEAD OF

ex:-

-- On Complex views we can not perform DML commands, To allow DML


operations then to write INSTEAD TRIGGERS

Ex:-

Table creations :
-----------------

Create table std_db( std_id varchar2(10), sname varchar2(10) );

Create table std_marks( std_id varchar2(10), maths number(5,2), Phys


number(5,2), chem number(5,2));

Create a complex view :


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

Create or replace view std_comp_view


as
select s.std_id, s.sname, sm.maths, sm.phys, sm.chem
from std_db s, std_marks sm
where s.std_id = sm.std_id;

SQL> Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 );


Insert into std_comp_view values ( 's1', 'king', 90, 89, 90 )
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table

note: on complex views DML operations are not allowed, to allow DML
operations then to write INSTEAD of triggers

Trigger :
---------

Create or replace trigger std_comp_view_trig


INSTEAD OF INSERT on std_comp_view
for each row
Begin
Insert into std_db values ( :new.std_id, :new.sname );
Insert into std_marks values ( :new.std_id, :new.maths, :New.phys,
:New.chem);
End;
/

SQL> SELECT * FROM STD_DB;

no rows selected

SQL> SELECT * FROM STD_MARKS;


no rows selected

SQL> insert into std_comp_view values ( 's1', 'anand', 90, 89, 80 );

1 row created.

SQL> select * from std_db;

STD_ID SNAME
---------- ----------
s1 anand

SQL> select * from std_marks;

STD_ID MATHS PHYS CHEM


---------- ------ ------ ------
s1 90 89 80

IV. SCHEMA LEVEL TRIGGERS :


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

-> These Triggers are also called as DDL triggers

-> To write Triggers on DDL commands that type of Triggers are called as
SCHEMA LEVEL TRIGGERS

SCHEMA :- Collection of db objects

Ex:-

-- Write a trigger program to restrict DROP command on DB OBJECTS

Create or replace Trigger drop_trig


Before DROP on SCHEMA
BEGIN
raise_application_error(-20001, 'Access Denied!!!!!');
END;
/

testing :
---------

SQL> DROP TABLE EMP;


DROP TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP VIEW MY_VIEW;


DROP VIEW MY_VIEW
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP PROCEDURE EMP_PROC;


DROP PROCEDURE EMP_PROC
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> DROP TRIGGER HOLIDAY_TRIG;


DROP TRIGGER HOLIDAY_TRIG
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Access Denied!!!!!
ORA-06512: at line 2

SQL> drop trigger drop_trig;

Trigger dropped.

note: now DROP command is working

-- Trigger on TRUCATE Command

Create or replace trigger TRUNC_TRIG


BEFORE TRUNCATE ON SCHEMA
BEGIN
Raise_application_error(-20002, 'Truncate Command Restricted.....');
END;
/

Testing :-
***********

SQL> TRUNCATE TABLE EMP;


TRUNCATE TABLE EMP
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20002: Truncate Command Restricted.....
ORA-06512: at line 2

V. DB LEVEL Triggers :
----------------------

-> These triggers are executed on entire USER

-> DB LEVEL trigger events are LOGON / LOGOFF events

ex:-

-- write a trigger program to main user login details

Table creation :
----------------

Create table login_details( tid number(2), user_id varchar2(10),


user_name varchar2(20), login_time timestamp,
logout_time timestamp, Wrk_hrs varchar2(10)
);

Sequence for to generate tids :


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

Create sequence tid_seq


start with 1
increment by 1;

Trigger on LOGIN :
------------------

Create or replace trigger login_trig


AFTER LOGON ON SCHEMA
Begin
Insert into login_details values ( tid_seq.nextval, uid, user, sysdate,
null, null );
End;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME LOGIN_TIME


LOGOUT_TIME WRK_HRS
---------- ---------- -------------------- -----------------
----------------- -----------------

1 49 ORA8PM 28-OCT-23 08.42.11.000000 PM

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:08:56.000000

SQL> select sysdate - login_time from login_details where tid=1;

SYSDATE-LOGIN_TIME
-------------------------------------------------------------------------
--
+000000000 00:09:09.000000
SQL> select substr( sysdate - login_time,12,8 ) from login_details where
tid=1;

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:26

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:30

SQL> /

SUBSTR(SYSDATE-LOGIN_TIME,12,8)
--------------------------------
00:10:33

LOGOUT TRIGGER :
----------------

Create or replace trigger logout_trig


BEFORE LOGOFF ON SCHEMA
BEGIN
Update login_details set logout_time = sysdate where tid=( select
max(tid) from login_details );
Update login_details set wrk_hrs = substr( sysdate - login_time, 12, 8
) where tid=( select max(tid) from login_details );
END;
/

testing:-

connect to user:
----------------
username: ora8pm
password: tiger

SQL> select * from login_details;

TID USER_ID USER_NAME


---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
1 49 ORA8PM
28-OCT-23 08.42.11.000000 PM
28-OCT-23 08.53.33.000000 PM
00:11:22
TID USER_ID USER_NAME
---------- ---------- --------------------
LOGIN_TIME
-------------------------------------------------------------------------
--
LOGOUT_TIME
-------------------------------------------------------------------------
--
WRK_HRS
----------
3 49 ORA8PM
28-OCT-23 08.53.40.000000 PM

note: SCHEMA LEVEL & DB LEVEL Triggers are written and executed by DBA
only

** All created trigger names are stored in USER_TRIGGERS/USER_OBJECTS

SQL> Select Object_name from user_objects where object_type='TRIGGER';

OBJECT_NAME
-------------------------------------------------------------------------
--------
STD_COMP_VIEW_TRIG
EMP_DB_INS_TRIG
TRUNC_TRIG
LOGIN_TRIG
LOGOUT_TRIG

or

SQL> SELECT TRIGGER_NAME FROM USER_TRIGGERS;

TRIGGER_NAME
------------------------------
EMP_DB_INS_TRIG
STD_COMP_VIEW_TRIG
LOGIN_TRIG
TRUNC_TRIG
LOGOUT_TRIG

** to see the particular trigger body

SQL> select text from user_source where name='EMP_DB_INS_TRIG';

TEXT
-------------------------------------------------------------------------
-------------------------
trigger emp_db_ins_trig
Before Insert on EMP_DB
for each row
begin
-- select my_seq.nextval into :new.eno from dual; ** before
oracle 11g version
:new.eno := my_seq.nextval; -- oracle 11g feature
end;

8 rows selected.

** DROPPING TRIGGERS :
**********************

syn:- DROP TRIGGER <trigger_name>;

ex:- DROP TRIGGER MY_TRIG;

note: on Single table max. 12 triggers are allowed

TRIGGER ON BANK_TRANS TABLE :


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

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi2 SCOTT SEC ###### 21-OCT-23 C 4500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
----------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

Validations :
-------------

-> Tno should be generate automatically

-> Source Accno column value is mandatory

-> If trans. type is 'AT' then DACCNO column value is mandatory

-> Trans. date will take today date only

-> Trans. type should be accept 'd', 'w' or 'at' only

-> Min. Trans. Amt Rs.1/-

-> Source accno is mandatory & should be available in bank_master table


-> if trans. type is 'd' (deposit) then balance should be update in
bank_mas table

-> if trans. type is 'w' ( withdraw) then

i. check the available balance, if sufficient balance then


allow the trans.
and update the balance in bank_master
table

ii. if in-sufficient balance then to raise error message

-> if trans. type is 'at' then

-> first check the balance then allow the transaction.

-> if customer completed morethan 3 withdraws in a month then next


trans. onwards to charge RS.20/- extra

Sequence for to generate sequence nos. :


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

Create sequence tno_seq


start with 1
increment by 1;

Trigger Program :
-----------------

Create or replace trigger bank_trans_trig


Before Insert on Bank_Trans
for each row
declare
scnt number;
no_of_withdraws number;
Begin
If :new.Sacno is null then
raise_application_error(-20501, 'Source A/c No. is
Mandatory.....');
Elsif :new.ttype='at' then
if :new.Dacno is null then
raise_application_error(-20502, 'Destination A/c No. is
Mandatory.....');
end if;
End if;
:new.tdate := sysdate;
if :new.ttype not in ( 'd','w','at') then
raise_application_error(-20503, 'Invalid Transaction Type.....');
end if;
if :new.tamt<=0 then
raise_application_error (-20504, 'Min. Trans. Amt. Rs.1/-');
end if;

select count(*) into scnt from bank_mas where acno = :new.sacno;


if scnt=0 then
raise_application_error( -20505, 'Invalid Source A/c No.');
end if;
if :new.ttype='d' then
Bank_Pack.credit( :new.sacno, :new.tamt ); -- credit
procedure is calling
elsif :new.ttype='w' then

Select count(*) into no_of_withdraws from bank_trans


where sacno = :new.sacno
and
ttype = 'w'
and
to_char(tdate,'mm-yyyy') = to_char(sysdate,'mm-
yyyy' );
if no_of_withdraws >=3 then
:new.tamt := :new.tamt + 20;
end if;

if ( bank_pack.chk_bal(:new.sacno) - :new.tamt ) >0 then


Bank_Pack.debit( :new.sacno, :new.tamt );
else
raise_application_error(-20506, 'In-sufficient Balance and your
withdraw power is Rs.'||bank_pack.chk_bal(:new.sacno));
end if;
elsif :new.ttype='at' then
if ( bank_pack.chk_bal(:new.sacno) - :new.tamt ) >0 then
Bank_Pack.Acc_trans( :new.sacno, :new.dacno, :new.tamt );
else
raise_application_error(-20506, 'In-sufficient Balance and your
Transfer power is Rs.'||bank_pack.chk_bal(:new.sacno));
end if;
end if;
:new.tno := tno_seq.nextval;
End;
/

Testing :
---------

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi1 SCOTT SEC ###### 21-OCT-23 C 6500
sbi2 KING HYD ###### 31-OCT-23 S 1500

SQL> desc bank_trans;


Name Null? Type
----------------------------------------------------- -------- ---------
---------------------------
TNO
NUMBER(10)
SACNO
VARCHAR2(10)
DACNO
VARCHAR2(10)
TDATE DATE
TTYPE CHAR(2)
TAMT
NUMBER(8,2)

DEPOSIT AMT :
*************

SQL> insert into bank_trans(sacno, ttype, tamt ) values ( 'sbi1', 'd',


1000 );
amt. deposited.

1 row created.

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A BAL


---------- ---------- -------------------- -------- --------- - ------
sbi1 SCOTT SEC ###### 21-OCT-23 C 7500
sbi2 KING HYD ###### 31-OCT-23 S 1500

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


------ ---------- ---------- --------- -- ------
1 sbi1 31-OCT-23 d 1000

Withdraw amount :
*****************

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
7500
sbi2 KING HYD 9000994007 31-OCT-23 S
1500

SQL> SELECT * FROM BANK_TRANS;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1', 'w',
600 );
amt. withdraw successfully

1 row created.

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
6900
sbi2 KING HYD 9000994007 31-OCT-23 S
1500

SQL> SELECT * FROM BANK_TRANS;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600

Amt.Transfer :
--------------

SQL> SELECT * FROM BANK_MAS;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
6900
sbi2 KING HYD 9000994007 31-OCT-23 S
1500

SQL> SELECT * FROM BANK_TRANS;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600

SQL> insert into bank_trans( sacno, dacno, ttype, tamt ) values ( 'sbi1',
'sbi2', 'at', 1500 );
amt. withdraw successfully
amt. deposited.
Amt. Transfer successfully.

1 row created.

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600
3 sbi1 sbi2 01-NOV-23 at 1500

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
5400
sbi2 KING HYD 9000994007 31-OCT-23 S
3000
INVALID INPUT :
***************

SQL> select * from bank_mas;

ACNO CNAME ADDR MOBILENO ODATE A


BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
5400
sbi2 KING HYD 9000994007 31-OCT-23 S
3000

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi10','d',


15000 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi10','d', 15000
)
*
ERROR at line 1:
ORA-20505: Invalid Source A/c No.
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 22
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

Invalid ttype :
---------------

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','x',


15000 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','x', 15000 )
*
ERROR at line 1:
ORA-20503: Invalid Transaction Type.....
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 14
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

Wrong amt input :


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

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


15000 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w', 15000 )
*
ERROR at line 1:
ORA-20506: In-sufficient Balance and your withdraw power is Rs.5400
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 45
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w', -


1500 );
insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w', -1500 )
*
ERROR at line 1:
ORA-20504: Min. Trans. Amt. Rs.1/-
ORA-06512: at "ORA8PM.BANK_TRANS_TRIG", line 17
ORA-04088: error during execution of trigger 'ORA8PM.BANK_TRANS_TRIG'

to check No.of Withdraws :


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

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> insert into bank_trans( sacno, ttype, tamt ) values ( 'sbi1','w',


100 );
amt. withdraw successfully

1 row created.

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


---------- ---------- ---------- --------- -- ----------
1 sbi1 31-OCT-23 d 1000
2 sbi1 01-NOV-23 w 600
3 sbi1 sbi2 01-NOV-23 at 1500
4 sbi1 01-NOV-23 w 100
5 sbi1 01-NOV-23 w 100
6 sbi1 01-NOV-23 w 120
7 sbi1 01-NOV-23 w 120
8 sbi1 01-NOV-23 w 120
9 sbi1 01-NOV-23 w 120

9 rows selected.

SQL> select * from bank_mas;


ACNO CNAME ADDR MOBILENO ODATE A
BAL
---------- ---------- -------------------- ---------- --------- - -------
---
sbi1 SCOTT SEC 9000994006 21-OCT-23 C
4720
sbi2 KING HYD 9000994007 31-OCT-23 S
3000

COMPOSITE DATATYPES :
---------------------

-> It is also called as USER-DEFINED DATATYPES

ARRAY ->

x[1] = 10;
x[2] = 20;
x[3] = 30;
.
.
x[10]= 100;

x number;

x=100;
x=200;

N[1]=SMITH
N[2]=ALLEN
N[]
.
.
N[14]=MILLER

P[1]=900
P[2]=1700
P[]
.
.
P[14]=1400

DECLARE
TYPE NAMES IS TABLE OF EMP.ENAME%TYPE INDEX BY BINARY_INTEGER;
TYPE PAYS IS TABLE OF EMP.SAL%TYPE INDEX BY BINARY_INTEGER;

-- N, P are table type variables

N NAMES;
P PAYS;
CNT NUMBER := 1;
BEGIN
-- FILLING N,P ARRAY ELEMENTS
FOR I IN ( SELECT ENAME, SAL FROM EMP )
LOOP
N(CNT) := I.ENAME;
P(CNT) := I.SAL;
CNT := CNT + 1; -- 3
END LOOP;

-- DISPLAYING N,P ARRAY ELEMENTS

FOR K IN N.FIRST..N.LAST -- 1..14


LOOP
DBMS_OUTPUT.PUT_LINE( N(K)||'............'||P(K));
END LOOP;
END;
/

SMITH............900
ALLEN............1700
WARD............1350
JONES............3075
MARTIN............1350
BLAKE............2950
CLARK............2550
HEMANTH............3100
KING............5100
TURNER............1600
ADAMS............1200
JAMES............1050
FORD............3100
MILLER............1400

PL/SQL procedure successfully completed.

BULK COLLECT INTO CLAUSE :


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

-> USED TO COPIES DB COLUMN VALUES INTO PL/SQL VARIABLES

-> PL/SQL VARIABLES SHOULD BE A TABLE TYPE VARIABLES

EXAMPLE:
--------

DECLARE
TYPE NAMES IS TABLE OF EMP.ENAME%TYPE INDEX BY BINARY_INTEGER;
TYPE PAYS IS TABLE OF EMP.SAL%TYPE INDEX BY BINARY_INTEGER;

-- N, P are table type variables

N NAMES;
P PAYS;
CNT NUMBER := 1;
BEGIN
-- FILLING N,P ARRAY ELEMENTS

SELECT ENAME, SAL BULK COLLECT INTO N, P FROM EMP;

-- DISPLAYING N,P ARRAY ELEMENTS


FOR K IN N.FIRST..N.LAST -- 1..14
LOOP
DBMS_OUTPUT.PUT_LINE( N(K)||'............'||P(K));
END LOOP;
END;
/

-- write a pl/sql block to display total all employee records

Declare
type emp_type is table of emp%rowtype index by Binary_Integer;
e emp_type;
cnt number := 1;
Begin

-- FILLING TOTAL ALL RECORDS OF EMP TABLE INTO E ARRAY

SELECT * BULK COLLECT INTO E FROM EMP;

-- Displaying ARRAY records

FOR I IN E.FIRST..E.LAST -- 1..14


LOOP
DBMS_OUTPUT.PUT_LINE( E(i).empno||' '|| e(i).ename ||'
'||e(i).job||' '||e(i).mgr||' '||e(i).sal||' '||e(i).hiredate||' '||
nvl( e(i).comm, 0 ) ||' '||e(i).deptno);
END LOOP;
End;
/

7369 SMITH CLERK 7902 900 17-DEC-80 0 20


7499 ALLEN SALESMAN 7698 1700 20-FEB-81 300 30
7521 WARD SALESMAN 7698 1350 22-FEB-81 500 30
7566 JONES MANAGER 7839 3075 02-APR-81 0 20
7654 MARTIN SALESMAN 7698 1350 28-SEP-81 1400 30
7698 BLAKE MANAGER 7839 2950 01-MAY-81 0 30
7782 CLARK MANAGER 7839 2550 09-JUN-81 0 10
7788 HEMANTH ANALYST 7566 3100 09-DEC-82 0 20
7839 KING PRESIDENT 5100 17-NOV-81 0 10
7844 TURNER SALESMAN 7698 1600 08-SEP-81 0 30
7876 ADAMS CLERK 7788 1200 12-JAN-83 0 20
7900 JAMES CLERK 7698 1050 03-DEC-81 0 30
7902 FORD ANALYST 7566 3100 03-DEC-81 0 20
7934 MILLER CLERK 7782 1400 23-JAN-82 0 10

PL/SQL procedure successfully completed.

NAMED BLOCKS :
--------------
-> Named Block programs are stored in DB permanently

-> All Named Block Programs are start with CREATE statement

ex:- Stored Procedures, Functions, Packages & Triggers

SUB-PROGRAMS :
--------------

-> Sub-programs are NAMED BLOCK programs

-> Sub-programs are self contained blocks

-> Sub-programs are stored in DB permanently

-> Sub-programs two types

i. stored procedures

ii. user-defined records

i. Stored Procedures :
----------------------

-> A set of pl/sql programs stored in db permanently and performs a


task

-> While calling the stored procedures we can pass parameters and
maximum 32 parameters are supported

-> Stored Procedures main advantages are...

I. RE-USABILITY :

-> Once stored procedure created then we can executes


'n' no.of times

ex: LOGIN PROCEDURE

II. MODULARITY :

-> A Huge program is devided into sub-programs

adv.

* easy to understand

* easy to debug the errors

III. It improves the Performance :

-> Stored procedures are stored in DB with Compiled


format, that why it improves the performance

-> Stored procedures are compiled only one time.

-> All created stored procedure names are stored in USER_OBJECTS table
( pre-defined table )
-> All stored procedure Bodies are stored in USER_SOURCE table ( pre-
defined table )

syn:-

Create or replace Procedure <procedure_name>


[( arg1 mode datatype, arg2 mode datatype,...)]
is
[<variable-declaration>;]
Begin
<exec-statements>;
[exception
<exec-statements>;]
end [<procedure_name>];
/

Ex:-

-- write a stored procedure to display WELCOME message

Create procedure my_proc


is
Begin
dbms_output.put_line( 'Welcome to Stored Procedures...');
End my_proc;
/

Executing stored procedure :


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

on sql prompt :
***************

syn:- Exec <procedure_name>;

ex:-

SQL> exec my_proc;


Welcome to Stored Procedures...

PL/SQL procedure successfully completed.

using PL/SQL Block :


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

syn:-

begin
<procedure_name>;
End;
/

ex:-

Begin
my_proc;
End;
/
Welcome to Stored Procedures...

PL/SQL procedure successfully completed.

-- write a stored procedure to find sum of two numbers

Create or replace procedure add_proc


is
x number(4) :=10;
y number(4) :=20;
Begin
dbms_output.put_line('Sum of two numbers = ' || ( x+y) );
End add_proc;
/

Procedure created.

SQL> exec add_proc;


Sum of two numbers = 30

PL/SQL procedure successfully completed.

SQL> exec add_proc;


Sum of two numbers = 30

PL/SQL procedure successfully completed.

** to take values at run time :


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

Create or replace procedure add_proc


is
x number(4) :=&x;
y number(4) :=&y;
Begin
dbms_output.put_line('Sum of two numbers = ' || ( x+y) );
End add_proc;
/

Enter value for x: 40


Enter value for y: 70

Procedure created.

SQL> exec add_proc;


Sum of two numbers = 110

PL/SQL procedure successfully completed.

SQL> exec add_proc;


Sum of two numbers = 110

PL/SQL procedure successfully completed.

note:

-> To execute above program, each and everytiem it returns same


output, bcz., procedures are compiled only Onetime

-> To overcome this problem, we can use Procedures with PARAMETERS


Stored Procedures with Parameters :
***********************************

-> While calling the procedures to pass parameter values is called as


procedure with parameters

-> Maximum 32 parameters are supported

ex:-

-- write a stored procedure to find sum of two numbers

Create or replace procedure add_proc


( x number, y number )
is
Begin
dbms_output.put_line('sum of two given numbers = ' || (x+y));
End add_proc;
/

SQL> exec add_proc( 100, 200 );


sum of two given numbers = 300

PL/SQL procedure successfully completed.

SQL> exec add_proc( 700, 899 );


sum of two given numbers = 1599

PL/SQL procedure successfully completed.

PROCEDURE Using INSERT command :


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

-- write a stored procedure to insert data into DEPT. table

Create or replace procedure dept_ins


( p_deptno dept.deptno%type,
p_dname dept.dname%type,
p_loc dept.loc%type )
is
Begin
Insert into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line( 'record inserted.');
End dept_ins;
/

SQL> exec dept_ins( 70, 'Eco', 'Hyd' );


record inserted.

PL/SQL procedure successfully completed.

SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
60 ADMIN SEC
70 Eco Hyd

6 rows selected.

SQL> exec dept_ins( 50, 'maths', 'sec' );


record inserted.

PL/SQL procedure successfully completed.

SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
60 ADMIN SEC
70 Eco Hyd
50 maths sec

7 rows selected.

** to see the PROCEDURE error messages

SQL> show errors


Errors for PROCEDURE EMP_INCR_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
12/5 PLS-00113: END identifier 'EMP_INCR' must match 'EMP_INCR_PROC'
at line 1, column 11

Stored Procedure using UPDATE command :


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

-- write a stored procedure to increment employee salary based on given


PCT.

Create or replace procedure emp_incr_proc


( p_empno emp.empno%type,
p_pct number )
is
begin
update emp set sal = sal + sal * p_pct /100 where empno = p_empno;
if sql%found then
dbms_output.put_line('salary incremented');
else
dbms_output.put_line('Employ record not found.');
end if;
End emp_incr_proc;
/

SQL> exec emp_incr_proc( 7839, 10 );


salary incremented
PL/SQL procedure successfully completed.

SQL> exec emp_incr_proc( 9000, 50 );


Employ record not found.

PL/SQL procedure successfully completed.

PROCEDURE using DELETE command :


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

Create or replace procedure EMP_DEL


( P_EMPNO EMP.EMPNO%TYPE )
is
Begin
DELETE FROM EMP WHERE EMPNO = P_EMPNO;
if sql%found then
dbms_output.put_line('record deleted successfully.');
else
dbms_output.put_line('employ record not found.');
end if;
End EMP_DEL;
/

SQL> EXEC EMP_DEL( 7902 );


record deleted successfully.

PL/SQL procedure successfully completed.

SQL> EXEC EMP_DEL( 7902 );


employ record not found.

PL/SQL procedure successfully completed.

PROCEDURES using CURSORS :


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

-- write a stored procedure declare bonus of every employee based on


given conditions

if employee GRADE is 1 or 2 then 50%

if employee grade is 3 or 4 then 30%

for other grades 10%

and bonus details should be stored employee bonus table

Create BONUS TABLE :


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

Create table BONUS_DB( Empid Number(4), Bonus_Date Date, Grade


Number(4), Bonus_Amt Number(8,2) );

Procedure :
-----------

Create or replace procedure Emp_Bonus_Proc


is
CURSOR e_cur is SELECT EMPNO, SAL, GRADE FROM EMP, SALGRADE WHERE SAL
BETWEEN LOSAL AND HISAL;
e e_cur%rowtype;
v_bonus Number;
Begin
open e_cur;
if e_cur%isopen then
dbms_output.put_line('cursor opened successfully.');
end if;
Loop
fetch e_cur into e;
exit when e_cur%notfound;
if e.grade in ( 1, 2 ) then
v_bonus := e.sal * 0.5;
elsif e.grade in ( 3, 4 ) then
v_bonus := e.sal * 0.3;
else
v_bonus := e.sal * 0.1;
end if;
Update emp set sal = sal + v_bonus where empno = e.empno;
Insert into Bonus_db values( e.empno, sysdate, e.grade, v_bonus );
End Loop;
dbms_output.put_line('Bonus Declared Successfully.');
close e_cur;
End emp_bonus_Proc;
/

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

14 rows selected.

SQL> exec emp_bonus_proc;


cursor opened successfully.
Bonus Declared Successfully.

PL/SQL procedure successfully completed.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2080 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 3867.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 3705 30
7782 CLARK MANAGER 7839 09-JUN-81 3185 10
7788 SCOTT ANALYST 7566 09-DEC-82 3900 20
7839 KING PRESIDENT 17-NOV-81 5500 10
7844 TURNER SALESMAN 7698 08-SEP-81 1950 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 03-DEC-81 3900 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

14 rows selected.

SQL> select * from bonus_db;

EMPID BONUS_DAT GRADE BONUS_AMT


------ --------- ------ ---------
7369 18-DEC-23 1 400
7876 18-DEC-23 1 550
7900 18-DEC-23 1 475
7521 18-DEC-23 2 625
7654 18-DEC-23 2 625
7934 18-DEC-23 2 650
7499 18-DEC-23 3 480
7844 18-DEC-23 3 450
7566 18-DEC-23 4 892.5
7698 18-DEC-23 4 855
7782 18-DEC-23 4 735
7788 18-DEC-23 4 900
7902 18-DEC-23 4 900
7839 18-DEC-23 5 500

14 rows selected.

PROCEDURES with PARAMETER MODES :


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

-> Parameter modes are specifies type of PARAMETER

-> PL/SQL supports two types of Parameter modes

i. IN

ii. OUT

iii. IN OUT

i. IN :
-------

-> This parameter mode specifies taking input into PROCEDURE

-> On IN parameter mode variables Assignment Targets ( := ) are not


supported

-> By default Parameter modes are IN


ex:-

Create or replace procedure add_proc( x IN number, y IN number )


is
begin
dbms_output.put_line('Sum of two Numbers = '|| (x+y));
End add_proc;
/

SQL> Create or replace procedure add_proc( x IN number, y IN number )


is
begin
dbms_output.put_line('Sum of two Numbers = '|| (x+y));
End add_proc;
/

Procedure created.

SQL> EXEC ADD_PROC(100, 500 );


Sum of two Numbers = 600

PL/SQL procedure successfully completed.

On IN parameter mode variables Assignment Targets ( := ) are not


supported :
*************************************************************************
***

SQL> Create or replace procedure add_proc( x IN number, y IN number )


is
begin
x := 5000;
dbms_output.put_line('Sum of two Numbers = '|| (x+y));
End add_proc;
/

Warning: Procedure created with compilation errors.

SQL> show errors


Errors for PROCEDURE ADD_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
4/8 PL/SQL: Statement ignored
4/8 PLS-00363: expression 'X' cannot be used as an assignment target

ii. OUT :
---------

-> Procedures are may / may not RETURN values

-> Procedures are RETURN Values by using OUT parameter modes

-> On OUT parameter mode variablesAssignment Targets are supported

ex:-
-- write a stored procedure to find sum of two given numbers and return
the output

Create or replace procedure add_proc( x IN number, y IN number, z OUT


number )
is
Begin
z := x + y;
End Add_Proc;
/

Calling procedure :
-------------------

ON SQL Prompt :
***************

SQL> variable res number;


SQL> exec add_proc(100,500, :res );

PL/SQL procedure successfully completed.

SQL> print :res;

RES
------
600

using PL/SQL Block :


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

SQL> declare
result number;
begin
add_proc(500, 400 , result );
dbms_output.put_line( 'sum of two given numbers = '||result);
end;
/
sum of two given numbers = 900

PL/SQL procedure successfully completed.

EX:-

-- Write a stored procedure to input EMPNO and return NETSALARY

Create or replace procedure emp_netsal_Proc( p_empno IN emp.empno%type,


p_netsal OUT Number )
IS
Begin
Select sal + nvl( comm,0 ) into p_Netsal from emp where empno = p_empno;
End emp_netsal_Proc;
/

calling procedure :
*******************

declare
v_netsal Number;
Begin
emp_netsal_Proc( &empno, v_netsal); -- calling procedure
dbms_output.put_line('Given Employ Net Sal Rs.'||v_netsal);
End;
/

Enter value for empno: 7788


Given Employ Net Sal Rs.3900

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7521
Given Employ Net Sal Rs.2375

PL/SQL procedure successfully completed.

Ex:-

-- write a stored procedure to input employ no and return grade

Create or replace procedure emp_grade( p_empno IN emp.empno%type,


p_grade OUT Number )
is
Begin
select grade into p_grade from emp, salgrade where sal between losal and
hisal and empno=p_empno;
End emp_grade;
/

calling procedure :
-------------------

declare
v_grade number;
begin
emp_grade( &empno, v_grade );
dbms_output.put_line( 'Emp Grade is ' || v_grade );
end;
/

Enter value for empno: 7839


Emp Grade is 5

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7369
Emp Grade is 1

PL/SQL procedure successfully completed.

Ex:-

-- write a stored procedure to input AadharNo. and return corresponding


customer details

create a customer table :


*************************
SQL> Create table customer_db ( cid number(4), cust_name varchar2(10),
cust_desig varchar2(20),
cust_db date, aadharNo Number(12) );

copying data from EMP table :


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

Insert into customer_db ( cid, cust_name, cust_desig, cust_db )


( select empno ,ename, job, hiredate from emp );

generating aadharnos:
---------------------

SQL> update customer_db set aadharno = 99999+rownum;

14 rows updated.

SQL> select * from customer_db;

CID CUST_NAME CUST_DESIG CUST_DB AADHARNO


------ ---------- -------------------- --------- --------
7369 SMITH CLERK 17-DEC-80 100000
7499 ALLEN SALESMAN 20-FEB-81 100001
7521 WARD SALESMAN 22-FEB-81 100002
7566 JONES MANAGER 02-APR-81 100003
7654 MARTIN SALESMAN 28-SEP-81 100004
7698 BLAKE MANAGER 01-MAY-81 100005
7782 CLARK MANAGER 09-JUN-81 100006
7788 SCOTT ANALYST 09-DEC-82 100007
7839 KING PRESIDENT 17-NOV-81 100008
7844 TURNER SALESMAN 08-SEP-81 100009
7876 ADAMS CLERK 12-JAN-83 100010
7900 JAMES CLERK 03-DEC-81 100011
7902 FORD ANALYST 03-DEC-81 100012
7934 MILLER CLERK 23-JAN-82 100013

14 rows selected.

Stored Procedure :
******************

Create or replace Procedure Get_Info( p_aadharNo IN


customer_db.cid%type, -- 100001
p_cid OUT customer_db.cid%type,
p_cust_name OUT customer_db.cust_name%type,
p_cust_desig OUT
customer_db.cust_desig%type,
p_cust_db OUT customer_db.cust_db%type
)
is
Begin
Select cid, cust_name, cust_desig, cust_db into p_cid, p_cust_name,
p_cust_desig, P_cust_db
from customer_db where
aadharno = p_aadharno;
End Get_info;
/

calling procedure in BACKEND :


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

Declare
v_cid customer_db.cid%type;
v_cust_name customer_db.cust_name%type;
v_cust_desig customer_db.cust_desig%type;
v_cust_db customer_db.cust_db%type;
Begin
get_info( &aadharno, v_cid, v_cust_name, v_cust_desig, v_cust_db);
-- calling procedure
dbms_output.put_line( v_cid );
dbms_output.put_line( v_cust_name );
dbms_output.put_line( v_cust_desig );
dbms_output.put_line( v_cust_db );
End;
/

** write a stored procedure to a create user registration

** Create a user registration table with Tno, Customer Id, Accno,


User_name, Password, created date, created by

Validations :
-------------

-> Trans. No. should be generate automatically

-> User Name should not be repeated ( input )

-> Password should be start with an ALPHABET ( input )

-> Min. Length of Password is 6 characters

-> Enter Password and Confirm password should be same

-> Created date is today date automatically

-> Created by should be accept (Customer,Admin) ( input )

-> By default User Status is 1

-> User status should be accept either 1 / 0 ( input )

-> Status should be return (output)

step1 :

Table creation :
----------------

Create table bank_user_reg( Tno Number(4),


CId Number(10),
Accno Varchar2(10),
user_name Varchar2(15),
password varchar2(15),
Create_date timestamp,
created_by Varchar2(10),
user_status Number(1) check ( user_status in ( 1, 0
) )
);

step2 :
-------

-- create a sequence to generate tno automatically

Create sequence tno_seq


start with 1
increment by 1;

Step3 :
-------

-- Procedure for user registration

Create or replace procedure User_Registration_Proc( p_cid IN number,


p_accno IN varchar2,
p_user_name IN varchar2, --
king_sbi
p_password IN varchar2, --
king@123
p_cnf_password IN varchar2,
p_created_by IN varchar2,
p_status Out Varchar2
)
Is
Cnt Number;
Begin
Select count(*) Into cnt from bank_user_reg where user_name =
p_user_Name; -- if cnt=1 is exists, cnt=0 not exists
if cnt=1 then
p_status := 'UserName already Exists.....';
elsif ASCII( substr( p_password ,1,1) ) Not Between 65 and 90 and
ASCII( substr( p_password ,1,1) ) Not Between 97 and 122 then
p_status := 'Password should be start with an Alphabet..';
elsif length(p_password) <6 then
p_status := 'Min. Length of Password is 6 chars.';
elsif p_password != p_cnf_password then
p_status := 'Enter Password and Cnf. Passwords should be same..';
elsif p_created_by not in ( 'admin','customer') then
p_status := 'Invalid Role...';
else
Insert into bank_user_reg values( tno_seq.nextval, p_cid, p_accno,
p_user_name , p_password, sysdate, p_created_by, 1);
p_status := 'User Created Successfully...';
end if;
End User_Registration_Proc;
/

Calling procedure :
-------------------

Declare
v_status varchar2(100);
Begin
User_Registration_Proc( &cid, &accno, &username, &password,
&cnf_password, &created_by, v_status );
dbms_output.put_line( v_status );
End;
/

Enter value for cid: 11


Enter value for accno: 'sbi1'
Enter value for username: 'king_sbi'
Enter value for password: 'king@123'
Enter value for cnf_password: 'king@123'
Enter value for created_by: 'admin'
User Created Successfully...

PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 12
Enter value for accno: 'sbi2'
Enter value for username: 'sbi_kris'
Enter value for password: 'kris@786'
Enter value for cnf_password: 'kris@786'
Enter value for created_by: 'customer'
User Created Successfully...

PL/SQL procedure successfully completed.

SQL> select * from bank_user_reg;

TNO CID ACCNO USER_NAME PASSWORD


------ ------ ---------- --------------- ---------------
CREATE_DATE
CREATED_BY USER_STATUS
-------------------------------------------------------------------------
-- ---------- -----------
1 11 sbi1 king_sbi king@123
22-DEC-23 07.39.01.000000 AM
admin 1

2 12 sbi2 sbi_kris kris@786


22-DEC-23 07.39.42.000000 AM
customer 1

INVALID INPUTS :
-----------------

Declare
v_status varchar2(100);
Begin
User_Registration_Proc( &cid, &accno, &username, &password,
&cnf_password, &created_by, v_status );
dbms_output.put_line( v_status );
End;
/

Enter value for cid: 13


Enter value for accno: 'sbi3'
Enter value for username: 'scott_sbi'
Enter value for password: '123@scott'
Enter value for cnf_password: '123@scott'
Enter value for created_by: 'admin'
Password should be start with an Alphabet..

PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 13
Enter value for accno: 'sbi3'
Enter value for username: 'scott_sbi'
Enter value for password: 'king@123'
Enter value for cnf_password: '123@king'
Enter value for created_by: 'admin'
Enter Password and Cnf. Passwords should be same..

PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 13
Enter value for accno: 'sbi4'
Enter value for username: 'king_sbi'
Enter value for password: 'king@123'
Enter value for cnf_password: 'king@123'
Enter value for created_by: 'admin'
UserName already Exists.....

PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 13
Enter value for accno: 'sbi3'
Enter value for username: 'scott_sbi'
Enter value for password: 'scott'
Enter value for cnf_password: 'scott'
Enter value for created_by: 'admin'
Min. Length of Password is 6 chars.

PL/SQL procedure successfully completed.

** Write a stored procedure to input USERNAME & PASSWORD and return


Status

Create or replace procedure Login_Proc


( p_user_name IN bank_user_reg.user_name%type, -- king_sbi
p_password IN bank_user_reg.password%type, -- king
p_status OUT Varchar2
)
is
cnt Number;
Begin
Select count(1) Into cnt from bank_user_reg
where user_name = p_user_name
and
password = p_password;
if cnt=1 then
p_status := 'Login Successfully.';
else
p_status := 'Invalid UserName/Password';
end if;
End Login_Proc;
/

calling Procedure :
-------------------

Declare
v_status varchar2(100);
Begin
login_proc( &user_name, &password, v_status ); -- calling Procedure
dbms_output.put_line( v_status );
End;
/

Enter value for user_name: 'king_sbi'


Enter value for password: 'king@123'
Login Successfully.

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'king_sbi'
Enter value for password: 'king'
Invalid UserName/Password

PL/SQL procedure successfully completed.

iii. IN OUT :
-------------

-> To declare any parameter as IN OUT, that parameter is taking INPUT


into Procedure and RETURN output through procedure

ex:-

Create or replace procedure INOUT_proc( X IN OUT NUMBER )


is
Begin
X := x * x * x;
End INOUT_proc;
/

calling Procedure :
*******************

declare
res number(10) := &res; -- 10
Begin
Inout_proc( res );
dbms_output.put_line( 'Result = ' || res );
end;
/

Enter value for res: 10


Result = 1000

PL/SQL procedure successfully completed.


STORED PROCEDURES WITH DEFAULT ARGUMENTS :
******************************************

-> While calling the stored procedures if we are not passing value to
Parameters then by default
specified default values are taken.

-> Generally Default Parameters are placed in at the end of PARAMETERS


LIST

ex:-

-- stored procedure for to insert data into DEPT. table

Create or replace procedure dept_ins_Proc


( p_deptno dept.deptno%type,
p_dname dept.dname%type Default 'Unknown',
p_loc dept.loc%type Default 'Unknown'
)
is
Begin
Insert into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line('Record Inserted.');
End dept_ins_proc;
/

calling procedure :
*******************

SQL> Exec dept_ins_Proc( 50, 'MATHS' );


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown

SQL> Exec dept_ins_Proc( 60, 'HYD' );


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown
60 HYD Unknown
6 rows selected.

Note: In abvoe 2nd example, Dept.Name taken as 'HYD' and LOC taken as
'Unknown', because by default procedures calling according to
positions.

NOTATIONS :
-----------

-> Notation means, while calling the procedures to pass parameter


values according to corresponding Positions or by using Formal
arguments names, or both.

-> Procedures are supports three types of NOTATIONS

I. POSITIONAL NOTATIONS

II. NAMED NOTATIONS

III. MIXED NOTATIONS

I. POSITIONAL NOTATIONS :
-------------------------

-> While calling the procedures, to pass parameter values according


corresponding parameter positions is called as Positional Notations.

-> By default all procedures are calling by this methods only

ex:-

SQL> EXEC DEPT_INS_PROC( 50, 'MATHS', 'HYD' );


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD

II. NAMED NOTATIONS :


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

-> While calling the procedures, to pass parameter values by using


FORMAL ARGUMENT NAMES is called as NAMED NOTATIONS

ex:-

SQL> EXEC DEPT_INS_PROC( p_deptno=>60, p_loc=>'HYD', P_dname=>'ENG');


Record Inserted.

PL/SQL procedure successfully completed.


SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD
60 ENG HYD

6 rows selected.

III. MIXED NOTATIONS :


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

-> Both Positional and Named Notations

ex:-

SQL> EXEC DEPT_INS_PROC( 70, P_LOC=>'HYD');


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD
60 ENG HYD
70 Unknown HYD

7 rows selected.

** To see the created procedure Names

SQL> SELECT OBJECT_NAME FROM USER_OBJECTS WHERE OBJECT_TYPE='PROCEDURE';

OBJECT_NAME
-------------------------------------------------------------------------
-------------
INOUT_PROC
EMP_NETSAL_PROC
EMP_GRADE
GET_INFO
USER_REGISTRATION_PROC
LOGIN_PROC
ADD_PROC
MY_PROC
DEPT_INS
EMP_INCR_PROC
EMP_DEL
EMP_BONUS_PROC
DEPT_INS_PROC
13 rows selected.

** TO SEE THE PARTICULAR PROCEDURE BODY

SQL> SELECT TEXT FROM USER_SOURCE WHERE NAME='USER_REGISTRATION_PROC';


-- in WHERE clause Procedure name should be CAPITAL LETTERS

TEXT
-------------------------------------------------------------------------
---------------------------
procedure User_Registration_Proc( p_cid IN number,
p_accno IN varchar2,
p_user_name IN
varchar2, -- king_sbi
p_password IN
varchar2, -- king@123
p_cnf_password IN
varchar2,
p_created_by IN
varchar2,
p_status Out Varchar2
)
Is
Cnt Number;
Begin
Select count(*) Into cnt from bank_user_reg where user_name =
p_user_Name; -- if cnt=1 is exis
ts, cnt=0 not exists

if cnt=1 then
p_status := 'UserName already Exists.....';
elsif ASCII( substr( p_password ,1,1) ) Not Between 65 and 90 and
ASCII( substr( p_password ,1,1) ) Not Between 97 and 122 then
p_status := 'Password should be start with an Alphabet..';
elsif length(p_password) <6 then
p_status := 'Min. Length of Password is 6 chars.';
elsif p_password != p_cnf_password then
p_status := 'Enter Password and Cnf. Passwords should be same..';
elsif p_created_by not in ( 'admin','customer') then
p_status := 'Invalid Role...';
else
Insert into bank_user_reg values( tno_seq.nextval, p_cid, p_accno,
p_user_name , p_password, s
ysdate, p_created_by, 1);

p_status := 'User Created Successfully...';


end if;
End User_Registration_Proc;

28 rows selected.

** Dropping Procedures :
*************************

SYN:- DROP PROCEDURE <PROCEDURE_NAME>;


EX:- DROP PROCEDURE DEPT_INS_PROC;

II. USER DEFINED FUNCTIONS :


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

-> According to Client Requirements, developer write with his own


function name and own logic is called as
USER DEFINED FUNCTIONS

-> USER DEFINED FUNCTIONS are defined by USER

-> Function is a Self Contained Block

-> User defined fucntions should be return a value

-> User defind functions supports Parameters and Parameter Modes(IN,


OUT, INOUT )

-> User defined functions main advantages are.... :

i. Modularity

ii. Re-usability

iii. Improves the Performance

-> All created User Defined function Names are stored in USER_OBJECTS

-> All created User Defined Function Bodies are stored in USER_SOURCE
tables

Function Syntax :
-----------------

Create or replace function <function_name>


[( Arg1 Mode Datatype, Arg2 Mode Datatype,..)]
RETURN <datatype>
is
[<variable-declaration>;]
Begin
<exec-statements>;
[Exception
<exec-statatements>;]
End [<function_name>];
/

Ex:-

-- write a user defined function to find simple interest

SI = PTR/100;

Create or replace function Simple_Int( P Number, T Number, R Number )


Return Number
is
si Number;
Begin
si := P*T*(R/100);
return( si );
End Simple_Int;
/

Calling Function :
******************

on SQL prompt :
---------------

method 1:
---------

SQL> select Simple_int(1000,2,10) from dual;

SIMPLE_INT(1000,2,10)
---------------------
200

method 2 :
----------

SQL> variable res number;

SQL> exec :res := simple_int( 1000, 2, 10 );

PL/SQL procedure successfully completed.

SQL> print :res;

RES
------
200

method 3 :
----------

declare
result number;
begin
select simple_int(1000,2,10) into result from dual;
dbms_output.put_line('Simple Interest = ' || result );
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

method 4 :
----------

declare
result number;
begin
result := simple_int(1000,2,10);
dbms_output.put_line('Simple Interest = ' || result );
End;
/
Simple Interest = 200

PL/SQL procedure successfully completed.

method 5 :
----------

begin
dbms_output.put_line('Simple Interest = ' || simple_int(1000,2,10));
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

Ex2:-

-- Write a user defined function to input employee no. and return


corresponding employee experience

Create or replace function emp_exp


( p_empno IN Emp.empno%type )
return Number
is
expe Number;
Begin
select months_between(sysdate,hiredate)/12 Into expe from emp where
empno = p_empno;
return ( expe );
exception
when no_data_found then
return(-1);
End emp_exp;
/

SQL> select emp_exp(7788) from dual;

EMP_EXP(7788)
-------------
41.047

SQL> select emp_exp(9000) from dual;

EMP_EXP(9000)
-------------
-1

-- Function returns VARCHAR datatype

-- write a user defined function to input empno and return corresponding


employee DNAME

Create or replace function emp_dname( p_empno emp.empno%type )


Return Varchar2
is
v_dname dept.dname%type;
Begin
select dname into v_dname from dept where deptno=( select deptno
from emp where empno=p_empno ) ;
return ( v_dname ) ;
Exception
when no_data_found then
return( 'Employ Record Not Exists...' );
End Emp_Dname;
/

SQL> select emp_dname( 7788 ) from dual;

EMP_DNAME(7788)
-------------------------------------------------------------------------
---------------------------
RESEARCH

SQL> select emp_dname( 7521 ) from dual;

EMP_DNAME(7521)
-------------------------------------------------------------------------
---------------------------
SALES

SQL> select emp_dname( 7839 ) from dual;

EMP_DNAME(7839)
-------------------------------------------------------------------------
---------------------------
ACCOUNTING

SQL> select emp_dname( 9000 ) from dual;

EMP_DNAME(9000)
------------------------------------------------------------
Employ Record Not Exists...

Function returns BOOLEAN Datatype:


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

-- write a user defined function return EMPLOYEE Record Found or NOT

Create or replace function Emp_Find( p_empno emp.empno%type )


Return Boolean
is
cnt Number;
Begin
select count(1) into cnt from emp where empno = p_empno;
if cnt>0 then
return (true);
else
return( false );
end if;
End emp_find;
/

SQL> select emp_find(7788) from dual;


select emp_find(7788) from dual
*
ERROR at line 1:
ORA-06552: PL/SQL: Statement ignored
ORA-06553: PLS-382: expression is of wrong type

note: Above function returns TRUE(output) to SQL PROMPT but, SQL not
supported BOOLEAN datatype. So To call above function
in PL/SQL block we can call

Declare
flag boolean;
Begin
flag := emp_find( &empno ); -- here function is calling
if flag = true then
dbms_output.put_line( 'Employ Record Exists...');
else
dbms_output.put_line( 'Employ Record Not Exists...');
end if;
End;
/

Enter value for empno: 7788


Employ Record Exists...

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7369
Employ Record Exists...

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 9000
Employ Record Not Exists...

PL/SQL procedure successfully completed.

-- we can call functions in IF condition

begin
if emp_find(&empno) then -- function is calling
dbms_output.put_line( 'Employ Record Exists...');
else
dbms_output.put_line( 'Employ Record Not Exists...');
end if;
End;
/

Enter value for empno: 7788


Employ Record Exists...

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 9000
Employ Record Not Exists...
PL/SQL procedure successfully completed.

-- write a pl/sql block to insert data into CRIC INFO Table

table creation :
****************

Create table cric_info( cid varchar2(10),


fname varchar2(20),
mname varchar2(20),
lname varchar2(20)
);

ex:- Cric_info_proc( 'c1', 'ramesh sachin tendulkar' );

SQL> select substr('rama krishna',1,4) from dual;

SUBS
----
rama

SQL> select instr('rama krishna','k',1,1) from dual;

INSTR('RAMAKRISHNA','K',1,1)
----------------------------
6

SQL> select instr('rama krishna','a',1,1) from dual;

INSTR('RAMAKRISHNA','A',1,1)
----------------------------
2

SQL> select instr('rama krishna','a',1,2) from dual;

INSTR('RAMAKRISHNA','A',1,2)
----------------------------
4

Function for to return First Name :


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

Create or replace function Fname( cname varchar2 ) -- ramesh


sachin tendulkar
Return Varchar2
is
v_Fname cric_info.fname%type;
Begin
v_fname := substr(cname, 1, Instr(cname, ' ', 1 ,1 )-1 );
return( v_fname );
End fname;
/

Function for to return Last Name :


----------------------------------
Create or replace function Lname( cname varchar2 ) -- ramesh sachin
tendulkar
return varchar2
is
v_Lname cric_info.Lname%type;
Begin
v_Lname := Substr( Cname, Instr(cname, ' ', -1, 1)+1 );
return( v_lname);
End Lname;
/

Function for to return Middle Name :


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

Create or replace function MName( Cname varchar2 ) -- sachin


Return Varchar2
is
v_Mname cric_info.mname%type;
Begin
v_Mname := Trim( Rtrim( Ltrim(cname, fname(cname) ), Lname(cname) ) );
return( v_Mname);
End Mname;
/

Procedure :
------------

Create or replace Procedure cric_info_proc( cid varchar2, cname varchar2


) -- 'c1', 'ramesh sachin tendulkar'
is
Begin
Insert into cric_Info values( cid, fname(cname),
mname(cname),lname(cname));
dbms_output.put_line('record inserted.');
End cric_info_proc;
/

SQL> EXEC CRIC_INFO_PROC('c1','ramesh sachin tendulkar');


record inserted.

PL/SQL procedure successfully completed.

SQL> EXEC CRIC_INFO_PROC('c2','virot kholi');


record inserted.

PL/SQL procedure successfully completed.

SQL> EXEC CRIC_INFO_PROC('c3','mahendar singh dhono');


record inserted.

PL/SQL procedure successfully completed.

SQL> EXEC CRIC_INFO_PROC('c4','siva rama krishna raju');


record inserted.

PL/SQL procedure successfully completed.


SQL> select * from cric_info;

CID FNAME MNAME LNAME


---------- -------------------- -------------------- --------------------
c1 ramesh sachin tendulkar
c2 virot kholi
c3 mahendar singh dhono
c4 siva rama krishna raju

** To see the created Function Names

SQL> select object_name from user_objects where object_type='FUNCTION';

OBJECT_NAME
-------------------------------------------------------------------------
---------------------------
SIMPLE_INT
EMP_EXP
EMP_DNAME
EMP_FIND
FNAME
LNAME
MNAME

7 rows selected.

** To see the created function body

SQL> select text from user_source where name='FNAME';

TEXT
-------------------------------------------------------------------------
---------------------------
function Fname( cname varchar2 ) -- ramesh sachin tendulkar
Return Varchar2
is
v_Fname cric_info.fname%type;
Begin
v_fname := substr(cname, 1, Instr(cname, ' ', 1 ,1 )-1 );
return( v_fname );
End fname;

8 rows selected.

** Dropping Functions

syn:- Drop Function <function_name>;

ex:- Drop Function Even_Odd;

Packages :
----------
-> Package is a collection of Variables, Cursors, Procedures &
Functions

-> Packages are used to Improves the performance while accessing sub-
programs(Procedures & Functions) from client location

-> Packages are used to improves the performance while retriving


programs

-> Packages are supports OOPs features like Function OverLoading, Data
Abstraction & Encapsulation

-> Packages are supports Procedure OverLoading also

-> Packages will not support any PARAMETERS and Will Not return any
values

-> All created package names are stored in USER_OBJECTS( pre-defined


table )

-> All created package bodies are stored in USER_SOURCE tables

PACKAGES ARE TWO PARTS :


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

I. PACKAGE SPECIFICATION

II. PACKAGE BODY

I. PACKAGE SPECIFICATION :
--------------------------

-> It contains declaration of Variables, Cursors, Procedures &


Functions

II. PACKAGE BODY :


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

-> It contains definitions of Package Specificaiton

-- Write a Package Program to find given employee netsal, and to return


grade

Package Specification :
***********************

Create or replace Package my_pack


is

Procedure emp_netsal( p_empno emp.empno%type );


Function emp_grade( p_empno emp.empno%type) return number;
End my_pack;
/

PACKAGE BODY :
**************

Create or replace Package Body my_pack


is

-- procedure body

Procedure emp_netsal( p_empno emp.empno%type )


is
v_netsal number;
begin
select sal + nvl(comm,0) into v_netsal from emp where empno=p_empno;
dbms_output.put_line(p_empno||' Employee Net Salary Rs.'||v_netsal);
Exception
when no_data_found then
raise_application_error(-20001, 'Employ Record Not Found.');
End Emp_Netsal;

-- Function Body

Function emp_grade( p_empno emp.empno%type) return number


is
v_grade Number;
Begin
select grade into v_grade from emp, salgrade
where sal between losal and hisal
and
empno = p_empno;
return( v_grade );
Exception
when no_data_found then
return( 0 );
End emp_grade;

End my_pack;
/

Calling Package Programs :


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

-- calling procedure

SQL> Exec my_pack.emp_netsal( 7369 );


7369 Employee Net Salary Rs.1200

PL/SQL procedure successfully completed.

SQL> Exec my_pack.emp_netsal( 9000 );


BEGIN my_pack.emp_netsal( 9000 ); END;

*
ERROR at line 1:
ORA-20001: Employ Record Not Found.
ORA-06512: at "ORA7AM.MY_PACK", line 14
ORA-06512: at line 1

-- Calling Function

SQL> select my_pack.emp_grade( 7369 ) from dual;


MY_PACK.EMP_GRADE(7369)
-----------------------
1

SQL> select my_pack.emp_grade( 7839 ) from dual;

MY_PACK.EMP_GRADE(7839)
-----------------------
5

SQL> select my_pack.emp_grade( 9000 ) from dual;

MY_PACK.EMP_GRADE(9000)
-----------------------
0

Function OverLoading :
**********************

-> Function Name is same and it supports different types of


Parameters/Arguments is called as Function Overloading

-> If no.of parameters are same then Corresponding parameters Datatype


should be different

Ex:-

Package Specification :
***********************

Create or replace package Fo_Pack


is
Function addval( x number, y number ) return number;
Function addval( x number, y number, z number ) return Number;
Function addval( str1 varchar2, str2 varchar2 ) return Varchar2;
End Fo_pack;
/

PACKAGE BODY :
**************

Create or replace package Body Fo_Pack


is
Function addval( x number, y number ) return number
is
Begin
Return( x + y );
End addval;

Function addval( x number, y number, z number ) return Number


is
Begin
Return( x + y + z );
End addval;

Function addval( str1 varchar2, str2 varchar2 ) return Varchar2


is
Begin
Return( str1 || ' ' || str2 );
End addval;

End Fo_pack;
/

SQL> select fo_pack.addval(100,200) from dual;

FO_PACK.ADDVAL(100,200)
-----------------------
300

SQL> select fo_pack.addval(100,200,500) from dual;

FO_PACK.ADDVAL(100,200,500)
---------------------------
800

SQL> select fo_pack.addval('naresh', 'it') from dual;

FO_PACK.ADDVAL('NARESH','IT')
-------------------------------------------------------------
naresh it

Procedure OverLoading :
-----------------------

-> Procedure Name is same and it supports different types of


Parameters/Arguments is called as Procedure Overloading

-> If no.of parameters are same then Corresponding parameters Datatype


should be different

Packages using CURSORS( REF CURSORS ) :


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

-- Write a package program to input dept no. and return corresponding


employee details

Create or replace package P1


is
Type r_cur is ref cursor;
status varchar2(100);
End P1;
/

note: to declare any variables,cursors,procedures & function inside


package specification
all are called as GLOBAL, these are we can access any where inside
the USER

Procedure for to return EMPLOY DETAILS and Procedure return Multiple


Records:
*************************************************************************
****

Create or replace Procedure get_details( p_deptno IN emp.deptno%type,


d_cur OUT p1.r_cur
)
is
Begin
OPen d_cur for select * from emp where deptno=p_deptno;
End get_details;
/

Calling Procedure :
-------------------

declare
v_cur P1.r_cur;
e emp%rowtype;
Begin
GET_DETAILS( &Deptno, v_cur ); -- calling procedure
loop
fetch v_cur into e;
exit when v_cur%notfound;
dbms_output.put_line( e.empno ||' '|| e.ename||' '||e.job||'
'||e.mgr||' '||e.hiredate||' '||e.sal||' '||e.deptno);
end loop;
close v_cur;
p1.status := 'Program Executed Successfully.';
dbms_output.put_line( p1.status );
End;
/

Enter value for deptno: 10


7782 CLARK MANAGER 7839 09-JUN-81 3185 10
7839 KING PRESIDENT 17-NOV-81 5500 10
7934 MILLER CLERK 7782 23-JAN-82 1950 10
Program Executed Successfully.

PL/SQL procedure successfully completed.

SQL> /
Enter value for deptno: 30
7499 ALLEN SALESMAN 7698 20-FEB-81 2080 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 30
7698 BLAKE MANAGER 7839 01-MAY-81 3705 30
7844 TURNER SALESMAN 7698 08-SEP-81 1950 30
7900 JAMES CLERK 7698 03-DEC-81 1425 30
Program Executed Successfully.

PL/SQL procedure successfully completed.

** to see the created package names

SQL> Select object_name from User_objects where object_type='PACKAGE';

OBJECT_NAME
-------------------------------------------------------------------------
---
MY_PACK
FO_PACK
P1

** To see the particular package body

SQL> select text from user_source where name='MY_PACK';

TEXT
-------------------------------------------------------------------------
---------------------------
Package my_pack
is

Procedure emp_netsal( p_empno emp.empno%type );


Function emp_grade( p_empno emp.empno%type) return number;
End my_pack;
Package Body my_pack
is

-- procedure body

Procedure emp_netsal( p_empno emp.empno%type )


is
v_netsal number;
begin
select sal + nvl(comm,0) into v_netsal from emp where empno=p_empno;
dbms_output.put_line(p_empno||' Employee Net Salary Rs.'||v_netsal);
Exception
when no_data_found then
raise_application_error(-20001, 'Employ Record Not Found.');
End Emp_Netsal;

-- Function Body

Function emp_grade( p_empno emp.empno%type) return number


is
v_grade Number;
Begin
select grade into v_grade from emp, salgrade
where sal between losal and hisal
and
empno = p_empno;
return( v_grade );
Exception
when no_data_found then
return( 0 );
End emp_grade;

End my_pack;

39 rows selected.

** Dropping Packages

Drop Package my_pack;


** Write a pl/sql block to Develop Following Modules

I. OPEN A NEW ACCOUNT (procedure)

II. VIEW ACCOUNT DETAILS (procedure)

III. DELETE ACCOUNT DETAILS(procedure)

IV. DEPOSIT AMOUNT(procedure)

V. WITHDRAW AMOUNT(procedure)

VI. TRANSFER AMOUNT (procedure)

VII. CHECK ACCOUNT BALANCE(function)

VIII. MINI STATEMENT(procedure)

IX. ACCOUNT STATEMENT(procedure)

Validations :
*************

bank_mas: Accno, cname, adddress, mobileno, mail id, account type,


opening date, & balance

bank_trans: Tno, SAccno, DAccno, Tdate, Ttype, & Tamount

I. OPEN A NEW ACCOUNT :


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

-> Account No. should be generate automatically

ex: sbi1, sbi2,.....

-> Customer name should be stored in as Capital letters

-> Mobile No. should not be accept duplicates

-> Mail id should not be accept duplicates

-> Account type should be accept S(savings), C(current a/c), or


AT(account transfer)

-> Account opening date will take system date automatically

-> Min. Account Opening Balance Rs.1000/-

II. VIEW ACCOUNT DETAILS :


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

-> To view account details by using ACCNO / MOBILENO

III. DELETE ACCOUNT DETAILS :


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

-> To delete account by using ACCNO


IV. DEPOSIT AMOUNT :
--------------------

-> Once amount is deposited then balance should be update

V. WITHDRAW AMOUNT :
--------------------

-> Once amount is withdrawn then balance should be update

VI. TRANSFER AMOUNT :


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

-> To Transfer amount from One account to Another Account

VII. CHECK ACCOUNT BALANCE :


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

-> To check account balance by using ACCNO / MOBILENO

VIII. MINI STATEMENT :


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

-> To generate latest/recent 5 transactions

IX. ACCOUNT STATEMENT :


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

-> To Generate account from two given dates

TABLE CREATIONS :
*****************

Bank_Mas :
----------

Create table Bank_mas( Acno Varchar2(10),


Cname Varchar2(10),
Address Varchar2(20),
Mobileno Number(10),
Mail_id Varchar2(20),
Acc_type Varchar2(2),
ODate Date,
Bal Number(8,2)
);

Bank_Trans :
************

Create Table Bank_Trans( Tno Number(4),


SAcno Varchar2(10),
DAcno Varchar2(10),
Tdate Date,
Ttype varchar2(2),
Tamt Number(8,2)
);
Sequence for to generate Acno Automatically :
*********************************************

Create Sequence acno_seq


start with 1
increment by 1;

*** Package Specification ****

Create or Replace Package Bank_Pack


is
-- Procedure Spec. for to open a new account

Procedure New_Acc( p_cname bank_mas.cname%type,


p_address bank_mas.address%type,
p_mobileno bank_mas.mobileno%type,
p_mail_id bank_mas.mail_id%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type,
p_odate bank_mas.odate%type default sysdate );

-- Procedure spec. for to view account details by using ACNO

Procedure View_Acc( p_acno Bank_mas.acno%type);

-- Procedure spec. for to view account details by using MOBILENO

Procedure View_Acc( p_mobileno Bank_mas.mobileno%type);

-- Procedure spec. for to Delete Account Details

Procedure Del_Acc( p_acno bank_mas.acno%type);

-- Procedure spec. for to Deposite Aamount

Procedure Credit( p_sacno bank_trans.Sacno%type,


p_tamt bank_trans.tamt%type);

-- Procedure Spec. for to Withdraw Amount

Procedure Debit( p_sacno bank_trans.Sacno%type,


p_tamt bank_trans.tamt%type);

-- Procedure Spec. for to Transfer amount by using ACNOs.

Procedure Acc_Trans( p_sacno bank_trans.Sacno%type,


p_Dacno bank_Trans.Dacno%type,
p_Tamt Bank_Trans.Tamt%type );

-- Function Spec. for to CHECK ACCOUNT Balance by using ACNO

Function Chk_Bal( p_acno bank_mas.acno%type ) Return Number;

-- Function spec. for to CHECK ACCOUNT Balance by using MOBILENO

Function Chk_Bal ( p_mobileno Bank_mas.Mobileno%type) Return Number;

-- Procedure spec. for to Generate Mini Statement


Procedure Mini_Stat( p_SAcno Bank_trans.sacno%type );

-- Procedure Spec. for to generate Account Statement

Procedure Acc_Stat( p_Sacno Bank_trans.Sacno%type,


p_Sdate date,
p_Edate date );
End Bank_Pack;
/

*** PACKAGE BODY ***

Create or replace Package Body Bank_Pack


is

-- Procedure Body for to open a new account

Procedure New_Acc( p_cname bank_mas.cname%type,


p_address bank_mas.address%type,
p_mobileno bank_mas.mobileno%type, -- 9000994005
p_mail_id bank_mas.mail_id%type,
p_acc_type bank_mas.acc_type%type, -- C
p_bal bank_mas.bal%type,
p_odate bank_mas.odate%type default sysdate )
is
Mobile_cnt number;
Mail_cnt Number;
Begin
Select count(*) into mobile_cnt from bank_mas where Mobileno =
p_mobileno;
Select count(*) into mail_cnt from bank_mas where Mail_id = p_Mail_id;

if mobile_cnt>0 then
raise_application_error(-20001, 'Mobileno already registered.');
elsif mail_cnt>0 then
raise_application_error(-20002, 'e-mail already registered.');
elsif upper(p_acc_type) not in ( 'C','S') then
raise_application_error(-20003, 'Invaid Account Type!!!!');
elsif p_bal <1000 then
raise_application_error(-20004, 'Min. Account Opening Balance
Rs.1000/-');
else
Insert into bank_mas values( 'sbi'||(acno_seq.nextval),
upper(p_cname), p_address, p_mobileno,
p_mail_id, p_acc_type,
p_odate, p_bal);
dbms_output.put_line('Account created successfully.');
end if;
End New_Acc;

-- Procedure body for to view account details by using ACNO

Procedure View_Acc( p_acno Bank_mas.acno%type)


is
bm bank_mas%rowtype;
Begin
Select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('********* ACCOUNT DETAILS ************');
dbms_output.put_line('Account No : ' || bm.acno);
dbms_output.put_line('Customer Name : ' || bm.cname);
dbms_output.put_line('Address : ' || bm.address);
dbms_output.put_line('MobileNo : ' || bm.Mobileno);
dbms_output.put_line('Mail Id : ' || bm.mail_id);
dbms_output.put_line('Account Type : ' || bm.acc_type);
dbms_output.put_line('Opening Date : ' || bm.Odate);
dbms_output.put_line('Balance : ' || bm.Bal);
dbms_output.put_line('********* END OF THE RECCORD *********');
exception
when no_data_found then
raise_application_error(-20002, 'Invalid Account No!!!!');
End View_Acc;

-- Procedure Body for to view account details by using MOBILENO

Procedure View_Acc( p_mobileno Bank_mas.mobileno%type)


is
bm bank_mas%rowtype;
Begin
Select * into bm from bank_mas where mobileno = p_mobileno ;
dbms_output.put_line('********* ACCOUNT DETAILS ************');
dbms_output.put_line('Account No : ' || bm.acno);
dbms_output.put_line('Customer Name : ' || bm.cname);
dbms_output.put_line('Address : ' || bm.address);
dbms_output.put_line('MobileNo : ' || bm.Mobileno);
dbms_output.put_line('Mail Id : ' || bm.mail_id);
dbms_output.put_line('Account Type : ' || bm.acc_type);
dbms_output.put_line('Opening Date : ' || bm.Odate);
dbms_output.put_line('Balance : ' || bm.Bal);
dbms_output.put_line('********* END OF THE RECCORD *********');
exception
when no_data_found then
raise_application_error(-20002, 'Invalid Mobile No!!!!');
End View_Acc;

-- Procedure spec. for to Delete Account Details

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from Bank_mas where Acno = p_acno;
if sql%found then
dbms_output.put_line('Record Deleted');
else
raise_application_error(-20003, 'Invalid Account No.!!!!!');
end if;
End Del_Acc;

-- Procedure Body for to Deposit Amount

Procedure Credit( p_sacno bank_trans.Sacno%type, -- sbi10


p_tamt bank_trans.tamt%type) -- -1000
is
Begin
update bank_mas set bal = bal + p_tamt where acno = p_sacno;
dbms_output.put_line('amt. credited');
End Credit;
-- Procedure body for to Withdraw Amount

Procedure Debit( p_sacno bank_trans.Sacno%type,


p_tamt bank_trans.tamt%type)
is
Begin
update bank_mas set bal = bal - p_tamt where acno = p_sacno;
dbms_output.put_line('amt. debited');
End Debit;

-- Procedure body for to Transfer amount by using ACNOs.

Procedure Acc_Trans( p_sacno bank_trans.Sacno%type,


p_Dacno bank_Trans.Dacno%type,
p_Tamt Bank_Trans.Tamt%type )
is
Begin
debit(p_sacno, p_tamt); -- debit procedure is calling
Credit(p_dacno, p_tamt); -- credit procedure is calling
dbms_output.put_line('Amt. Transfer Successfully.');
End Acc_Trans;

-- Function Body for to CHECK ACCOUNT Balance by using ACNO

Function Chk_Bal( p_acno bank_mas.acno%type ) Return Number


is
v_bal Number;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return( v_bal );
exception
when no_data_found then
return(-1);
End Chk_Bal;

-- Function Body for to CHECK ACCOUNT Balance by using MOBILENO

Function Chk_Bal ( p_mobileno Bank_mas.Mobileno%type) Return Number


is
v_bal Number;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return( v_bal );
exception
when no_data_found then
return(-1);
End Chk_Bal;

-- Procedure body for to Generate Mini Statement

Procedure Mini_Stat( p_SAcno Bank_trans.sacno%type )


is
Cursor Mini_cur is Select Sacno, Tdate, Ttype, Tamt from ( select
Sacno, Tdate, Ttype, Tamt from bank_trans
where SAcno =
p_SAcno order by tdate desc )
where
rownum <=5;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('***** MINI STATEMENT *****');
Loop
Fetch mini_cur into bt;
exit when mini_cur%notfound;

dbms_output.put_line(rpad(bt.Sacno,10)||rpad(bt.Tdate,10)||rpad(bt.Ttype,
10)||rpad(bt.Tamt,10));
End Loop;
Close Mini_cur;
dbms_output.put_line('***** END OF THE RECORDS *****');
End Mini_stat;

-- Procedure body for to generate Account Statement

Procedure Acc_Stat( p_Sacno Bank_trans.Sacno%type,


p_Sdate date,
p_Edate date )
is
Cursor acc_cur is select * from bank_trans where trunc(tdate)
between trunc(p_Sdate) and trunc(p_Edate)
and
Sacno = p_Sacno;
ac acc_cur%rowtype;
Begin
open acc_cur;
dbms_output.put_line('***** ACC STATEMENT *****');
Loop
fetch acc_cur into ac;
exit when acc_cur%notfound;
dbms_output.put_line(
rpad(ac.Sacno,10)||rpad(ac.Dacno,10)||rpad(ac.tdate,10)||rpad(ac.ttype,10
)||rpad(ac.tamt,10));
End Loop;
dbms_output.put_line('***** END OF THE RECORDS *****');
End Acc_stat;

End Bank_Pack;
/

Inserting data into bank_trans table :


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

Insert into bank_trans values(1,'sbi1',null, '24-dec-23', 'd', 1000 );


Insert into bank_trans values(2,'sbi2',null, '24-dec-23', 'w', 200 );
Insert into bank_trans values(3,'sbi1',null, '25-dec-23', 'w', 400 );
Insert into bank_trans values(4,'sbi1',null, '25-dec-23', 'd', 600 );
Insert into bank_trans values(5,'sbi2',null, '27-dec-23', 'd', 500 );
Insert into bank_trans values(6,'sbi1',null, '28-dec-23', 'd', 100 );
Insert into bank_trans values(7,'sbi1',null, '31-dec-23', 'w', 300 );
Insert into bank_trans values(8,'sbi1',null, '2-Jan-24', 'd', 1500 );
Insert into bank_trans values(9,'sbi1',null, '2-Jan-24', 'w', 200 );

commit;

SQL> select * from bank_trans;


TNO SACNO DACNO TDATE TT TAMT
------ ---------- ---------- --------- -- ------
1 sbi1 24-DEC-23 d 1000
2 sbi2 24-DEC-23 w 200
3 sbi1 25-DEC-23 w 400
4 sbi1 25-DEC-23 d 600
5 sbi2 27-DEC-23 d 500
6 sbi1 28-DEC-23 d 100
7 sbi1 31-DEC-23 w 300
8 sbi1 02-JAN-24 d 1500
9 sbi1 02-JAN-24 w 200

9 rows selected.

EXECUTE PACKAGE PROGRAME:


-----------*************

To Create a New Account :


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

SQL> Exec Bank_pack.new_acc( 'king', 'hyd',


9000994005,'[email protected]','s',1500 );
Account created successfully.

PL/SQL procedure successfully completed.

SQL> Exec Bank_pack.new_acc( 'scott', 'sec',


9000994006,'[email protected]','c',2400 );
Account created successfully.

PL/SQL procedure successfully completed.

SQL> set num 10;


SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 1500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

View Account Details :


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

SQL> Exec bank_pack.view_acc('sbi1');


********* ACCOUNT DETAILS ************
Account No : sbi1
Customer Name : KING
Address : hyd
MobileNo : 9000994005
Mail Id : [email protected]
Account Type : s
Opening Date : 04-JAN-24
Balance : 1500
********* END OF THE RECCORD *********

PL/SQL procedure successfully completed.

Delete Account Details :


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

SQL> exec bank_pack.del_acc('sbi1');


Record Deleted

PL/SQL procedure successfully completed.

Deposit Amount :
----------------

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 1500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

SQL> exec bank_pack.credit('sbi1',1000);


amt. credited

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 2500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

Withdraw Amt. :
---------------

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 2500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

SQL> exec bank_pack.debit('sbi1',200);


amt. debited
PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 2300
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

Tamount Transfer :
******************

SQL> Exec bank_pack.acc_trans('sbi1','sbi2',500);


amt. debited
amt. credited
Amt. Transfer Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 1800
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2900

To Check Account Balance by using ACNO:


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

SQL> select bank_pack.chk_bal('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
1800

To Check Account Balance by using MOBILENO:


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

SQL> select bank_pack.chk_bal(9000994006) from dual;

BANK_PACK.CHK_BAL(9000994006)
-----------------------------
2900

MINI STATEMENT :
****************
SQL> Exec Bank_pack.mini_stat('sbi1');

***** MINI STATEMENT *****


sbi1 02-JAN-24 d 1500
sbi1 02-JAN-24 w 200
sbi1 31-DEC-23 w 300
sbi1 28-DEC-23 d 100
sbi1 25-DEC-23 w 400
***** END OF THE RECORDS *****

PL/SQL procedure successfully completed.

Account Statement :
*******************

SQL> Exec Bank_pack.Acc_stat('sbi1','01-dec-23',sysdate);


***** ACC STATEMENT *****
sbi1 24-DEC-23 d 1000
sbi1 25-DEC-23 w 400
sbi1 25-DEC-23 d 600
sbi1 28-DEC-23 d 100
sbi1 31-DEC-23 w 300
sbi1 02-JAN-24 d 1500
sbi1 02-JAN-24 w 200
***** END OF THE RECORDS *****

PL/SQL procedure successfully completed.

TRIGGERS :
**********

-> A Set of Pl/Sql statements stored in DB permanently and


automatically executed whenever EVENT raising
statement is performed.

-> Triggers are executed WHENEVER DML operations(Events) are performed

-> Triggers are executed when the tables are manipulated by other users
or by other application s/w tools

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict User Defined Conditions or Business


Rules

-> All Created Trigger Names are stored in USER_TRIGGERS/USER_OBJECTS (


system table )

-> All Created Trigger Bodies are stored in USER_SOURCE ( system table
)

Trigger Parts :
***************

i. Trigger Event :
------------------

-> It indicates when to activate/execute the trigger

-> Trigger Events are...

a. Before Insert b. Before Update c. Before Delete


d. After Insert e. After Update f. After Delete

ii. Trigger Type :


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

-> It indicates type of the Trigger

-> There are two types of Triggers

a. Row Level Triggers

b. Statement Level Triggers

iii. Trigger Restriction :


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

-> It is used to stop automatic execution of code

iv. Trigger Body :


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

-> A set of PL/SQL statements

Trigger syn:-
*************

Create or replace Trigger <Trigger_Name>


Before/After INSERT or UPDATE or DELETE -- i
[of Columns] ON <table_name>
[For Each Row] -- ii
[When <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

NAMED BLOCKS :
--------------

-> Named Block programs are stored in DB permanently

-> All Named Block Programs are start with CREATE statement

ex:- Stored Procedures, Functions, Packages & Triggers

SUB-PROGRAMS :
--------------

-> Sub-programs are NAMED BLOCK programs

-> Sub-programs are self contained blocks


-> Sub-programs are stored in DB permanently

-> Sub-programs two types

i. stored procedures

ii. user-defined records

i. Stored Procedures :
----------------------

-> A set of pl/sql programs stored in db permanently and performs a


task

-> While calling the stored procedures we can pass parameters and
maximum 32 parameters are supported

-> Stored Procedures main advantages are...

I. RE-USABILITY :

-> Once stored procedure created then we can executes


'n' no.of times

ex: LOGIN PROCEDURE

II. MODULARITY :

-> A Huge program is devided into sub-programs

adv.

* easy to understand

* easy to debug the errors

III. It improves the Performance :

-> Stored procedures are stored in DB with Compiled


format, that why it improves the performance

-> Stored procedures are compiled only one time.

-> All created stored procedure names are stored in USER_OBJECTS table
( pre-defined table )

-> All stored procedure Bodies are stored in USER_SOURCE table ( pre-
defined table )

syn:-

Create or replace Procedure <procedure_name>


[( arg1 mode datatype, arg2 mode datatype,...)]
is
[<variable-declaration>;]
Begin
<exec-statements>;
[exception
<exec-statements>;]
end [<procedure_name>];
/

Ex:-

-- write a stored procedure to display WELCOME message

Create procedure my_proc


is
Begin
dbms_output.put_line( 'Welcome to Stored Procedures...');
End my_proc;
/

Executing stored procedure :


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

on sql prompt :
***************

syn:- Exec <procedure_name>;

ex:-

SQL> exec my_proc;


Welcome to Stored Procedures...

PL/SQL procedure successfully completed.

using PL/SQL Block :


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

syn:-

begin
<procedure_name>;
End;
/

ex:-

Begin
my_proc;
End;
/

Welcome to Stored Procedures...

PL/SQL procedure successfully completed.

-- write a stored procedure to find sum of two numbers

Create or replace procedure add_proc


is
x number(4) :=10;
y number(4) :=20;
Begin
dbms_output.put_line('Sum of two numbers = ' || ( x+y) );
End add_proc;
/

Procedure created.

SQL> exec add_proc;


Sum of two numbers = 30

PL/SQL procedure successfully completed.

SQL> exec add_proc;


Sum of two numbers = 30

PL/SQL procedure successfully completed.

** to take values at run time :


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

Create or replace procedure add_proc


is
x number(4) :=&x;
y number(4) :=&y;
Begin
dbms_output.put_line('Sum of two numbers = ' || ( x+y) );
End add_proc;
/

Enter value for x: 40


Enter value for y: 70

Procedure created.

SQL> exec add_proc;


Sum of two numbers = 110

PL/SQL procedure successfully completed.

SQL> exec add_proc;


Sum of two numbers = 110

PL/SQL procedure successfully completed.

note:

-> To execute above program, each and everytiem it returns same


output, bcz., procedures are compiled only Onetime

-> To overcome this problem, we can use Procedures with PARAMETERS

Stored Procedures with Parameters :


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

-> While calling the procedures to pass parameter values is called as


procedure with parameters

-> Maximum 32 parameters are supported

ex:-

-- write a stored procedure to find sum of two numbers


Create or replace procedure add_proc
( x number, y number )
is
Begin
dbms_output.put_line('sum of two given numbers = ' || (x+y));
End add_proc;
/

SQL> exec add_proc( 100, 200 );


sum of two given numbers = 300

PL/SQL procedure successfully completed.

SQL> exec add_proc( 700, 899 );


sum of two given numbers = 1599

PL/SQL procedure successfully completed.

PROCEDURE Using INSERT command :


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

-- write a stored procedure to insert data into DEPT. table

Create or replace procedure dept_ins


( p_deptno dept.deptno%type,
p_dname dept.dname%type,
p_loc dept.loc%type )
is
Begin
Insert into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line( 'record inserted.');
End dept_ins;
/

SQL> exec dept_ins( 70, 'Eco', 'Hyd' );


record inserted.

PL/SQL procedure successfully completed.

SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
60 ADMIN SEC
70 Eco Hyd

6 rows selected.

SQL> exec dept_ins( 50, 'maths', 'sec' );


record inserted.

PL/SQL procedure successfully completed.

SQL> select * from dept;


DEPTNO DNAME LOC
------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
60 ADMIN SEC
70 Eco Hyd
50 maths sec

7 rows selected.

** to see the PROCEDURE error messages

SQL> show errors


Errors for PROCEDURE EMP_INCR_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
12/5 PLS-00113: END identifier 'EMP_INCR' must match 'EMP_INCR_PROC'
at line 1, column 11

Stored Procedure using UPDATE command :


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

-- write a stored procedure to increment employee salary based on given


PCT.

Create or replace procedure emp_incr_proc


( p_empno emp.empno%type,
p_pct number )
is
begin
update emp set sal = sal + sal * p_pct /100 where empno = p_empno;
if sql%found then
dbms_output.put_line('salary incremented');
else
dbms_output.put_line('Employ record not found.');
end if;
End emp_incr_proc;
/

SQL> exec emp_incr_proc( 7839, 10 );


salary incremented

PL/SQL procedure successfully completed.

SQL> exec emp_incr_proc( 9000, 50 );


Employ record not found.

PL/SQL procedure successfully completed.

PROCEDURE using DELETE command :


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

Create or replace procedure EMP_DEL


( P_EMPNO EMP.EMPNO%TYPE )
is
Begin
DELETE FROM EMP WHERE EMPNO = P_EMPNO;
if sql%found then
dbms_output.put_line('record deleted successfully.');
else
dbms_output.put_line('employ record not found.');
end if;
End EMP_DEL;
/

SQL> EXEC EMP_DEL( 7902 );


record deleted successfully.

PL/SQL procedure successfully completed.

SQL> EXEC EMP_DEL( 7902 );


employ record not found.

PL/SQL procedure successfully completed.

PROCEDURES using CURSORS :


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

-- write a stored procedure declare bonus of every employee based on


given conditions

if employee GRADE is 1 or 2 then 50%

if employee grade is 3 or 4 then 30%

for other grades 10%

and bonus details should be stored employee bonus table

Create BONUS TABLE :


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

Create table BONUS_DB( Empid Number(4), Bonus_Date Date, Grade


Number(4), Bonus_Amt Number(8,2) );

Procedure :
-----------

Create or replace procedure Emp_Bonus_Proc


is
CURSOR e_cur is SELECT EMPNO, SAL, GRADE FROM EMP, SALGRADE WHERE SAL
BETWEEN LOSAL AND HISAL;
e e_cur%rowtype;
v_bonus Number;
Begin
open e_cur;
if e_cur%isopen then
dbms_output.put_line('cursor opened successfully.');
end if;
Loop
fetch e_cur into e;
exit when e_cur%notfound;
if e.grade in ( 1, 2 ) then
v_bonus := e.sal * 0.5;
elsif e.grade in ( 3, 4 ) then
v_bonus := e.sal * 0.3;
else
v_bonus := e.sal * 0.1;
end if;
Update emp set sal = sal + v_bonus where empno = e.empno;
Insert into Bonus_db values( e.empno, sysdate, e.grade, v_bonus );
End Loop;
dbms_output.put_line('Bonus Declared Successfully.');
close e_cur;
End emp_bonus_Proc;
/

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

14 rows selected.

SQL> exec emp_bonus_proc;


cursor opened successfully.
Bonus Declared Successfully.

PL/SQL procedure successfully completed.

SQL> select * from emp;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO


------ ---------- --------- ------ --------- ------ ------ ------
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2080 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7566 JONES MANAGER 7839 02-APR-81 3867.5 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 3705 30
7782 CLARK MANAGER 7839 09-JUN-81 3185 10
7788 SCOTT ANALYST 7566 09-DEC-82 3900 20
7839 KING PRESIDENT 17-NOV-81 5500 10
7844 TURNER SALESMAN 7698 08-SEP-81 1950 0 30
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7902 FORD ANALYST 7566 03-DEC-81 3900 20
7934 MILLER CLERK 7782 23-JAN-82 1950 10

14 rows selected.

SQL> select * from bonus_db;

EMPID BONUS_DAT GRADE BONUS_AMT


------ --------- ------ ---------
7369 18-DEC-23 1 400
7876 18-DEC-23 1 550
7900 18-DEC-23 1 475
7521 18-DEC-23 2 625
7654 18-DEC-23 2 625
7934 18-DEC-23 2 650
7499 18-DEC-23 3 480
7844 18-DEC-23 3 450
7566 18-DEC-23 4 892.5
7698 18-DEC-23 4 855
7782 18-DEC-23 4 735
7788 18-DEC-23 4 900
7902 18-DEC-23 4 900
7839 18-DEC-23 5 500

14 rows selected.

PROCEDURES with PARAMETER MODES :


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

-> Parameter modes are specifies type of PARAMETER

-> PL/SQL supports two types of Parameter modes

i. IN

ii. OUT

iii. IN OUT

i. IN :
-------

-> This parameter mode specifies taking input into PROCEDURE

-> On IN parameter mode variables Assignment Targets ( := ) are not


supported

-> By default Parameter modes are IN

ex:-

Create or replace procedure add_proc( x IN number, y IN number )


is
begin
dbms_output.put_line('Sum of two Numbers = '|| (x+y));
End add_proc;
/

SQL> Create or replace procedure add_proc( x IN number, y IN number )


is
begin
dbms_output.put_line('Sum of two Numbers = '|| (x+y));
End add_proc;
/

Procedure created.

SQL> EXEC ADD_PROC(100, 500 );


Sum of two Numbers = 600

PL/SQL procedure successfully completed.

On IN parameter mode variables Assignment Targets ( := ) are not


supported :
*************************************************************************
***

SQL> Create or replace procedure add_proc( x IN number, y IN number )


is
begin
x := 5000;
dbms_output.put_line('Sum of two Numbers = '|| (x+y));
End add_proc;
/

Warning: Procedure created with compilation errors.

SQL> show errors


Errors for PROCEDURE ADD_PROC:

LINE/COL ERROR
-------- ----------------------------------------------------------------
-
4/8 PL/SQL: Statement ignored
4/8 PLS-00363: expression 'X' cannot be used as an assignment target

ii. OUT :
---------

-> Procedures are may / may not RETURN values

-> Procedures are RETURN Values by using OUT parameter modes

-> On OUT parameter mode variablesAssignment Targets are supported

ex:-

-- write a stored procedure to find sum of two given numbers and return
the output

Create or replace procedure add_proc( x IN number, y IN number, z OUT


number )
is
Begin
z := x + y;
End Add_Proc;
/

Calling procedure :
-------------------

ON SQL Prompt :
***************

SQL> variable res number;


SQL> exec add_proc(100,500, :res );

PL/SQL procedure successfully completed.

SQL> print :res;

RES
------
600

using PL/SQL Block :


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

SQL> declare
result number;
begin
add_proc(500, 400 , result );
dbms_output.put_line( 'sum of two given numbers = '||result);
end;
/
sum of two given numbers = 900

PL/SQL procedure successfully completed.

EX:-

-- Write a stored procedure to input EMPNO and return NETSALARY

Create or replace procedure emp_netsal_Proc( p_empno IN emp.empno%type,


p_netsal OUT Number )
IS
Begin
Select sal + nvl( comm,0 ) into p_Netsal from emp where empno = p_empno;
End emp_netsal_Proc;
/

calling procedure :
*******************

declare
v_netsal Number;
Begin
emp_netsal_Proc( &empno, v_netsal); -- calling procedure
dbms_output.put_line('Given Employ Net Sal Rs.'||v_netsal);
End;
/

Enter value for empno: 7788


Given Employ Net Sal Rs.3900

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7521
Given Employ Net Sal Rs.2375

PL/SQL procedure successfully completed.

Ex:-

-- write a stored procedure to input employ no and return grade

Create or replace procedure emp_grade( p_empno IN emp.empno%type,


p_grade OUT Number )
is
Begin
select grade into p_grade from emp, salgrade where sal between losal and
hisal and empno=p_empno;
End emp_grade;
/

calling procedure :
-------------------

declare
v_grade number;
begin
emp_grade( &empno, v_grade );
dbms_output.put_line( 'Emp Grade is ' || v_grade );
end;
/

Enter value for empno: 7839


Emp Grade is 5

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7369
Emp Grade is 1

PL/SQL procedure successfully completed.

Ex:-

-- write a stored procedure to input AadharNo. and return corresponding


customer details

create a customer table :


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

SQL> Create table customer_db ( cid number(4), cust_name varchar2(10),


cust_desig varchar2(20),
cust_db date, aadharNo Number(12) );

copying data from EMP table :


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

Insert into customer_db ( cid, cust_name, cust_desig, cust_db )


( select empno ,ename, job, hiredate from emp );

generating aadharnos:
---------------------
SQL> update customer_db set aadharno = 99999+rownum;

14 rows updated.

SQL> select * from customer_db;

CID CUST_NAME CUST_DESIG CUST_DB AADHARNO


------ ---------- -------------------- --------- --------
7369 SMITH CLERK 17-DEC-80 100000
7499 ALLEN SALESMAN 20-FEB-81 100001
7521 WARD SALESMAN 22-FEB-81 100002
7566 JONES MANAGER 02-APR-81 100003
7654 MARTIN SALESMAN 28-SEP-81 100004
7698 BLAKE MANAGER 01-MAY-81 100005
7782 CLARK MANAGER 09-JUN-81 100006
7788 SCOTT ANALYST 09-DEC-82 100007
7839 KING PRESIDENT 17-NOV-81 100008
7844 TURNER SALESMAN 08-SEP-81 100009
7876 ADAMS CLERK 12-JAN-83 100010
7900 JAMES CLERK 03-DEC-81 100011
7902 FORD ANALYST 03-DEC-81 100012
7934 MILLER CLERK 23-JAN-82 100013

14 rows selected.

Stored Procedure :
******************

Create or replace Procedure Get_Info( p_aadharNo IN


customer_db.cid%type, -- 100001
p_cid OUT customer_db.cid%type,
p_cust_name OUT customer_db.cust_name%type,
p_cust_desig OUT
customer_db.cust_desig%type,
p_cust_db OUT customer_db.cust_db%type
)
is
Begin
Select cid, cust_name, cust_desig, cust_db into p_cid, p_cust_name,
p_cust_desig, P_cust_db
from customer_db where
aadharno = p_aadharno;
End Get_info;
/

calling procedure in BACKEND :


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

Declare
v_cid customer_db.cid%type;
v_cust_name customer_db.cust_name%type;
v_cust_desig customer_db.cust_desig%type;
v_cust_db customer_db.cust_db%type;
Begin
get_info( &aadharno, v_cid, v_cust_name, v_cust_desig, v_cust_db);
-- calling procedure
dbms_output.put_line( v_cid );
dbms_output.put_line( v_cust_name );
dbms_output.put_line( v_cust_desig );
dbms_output.put_line( v_cust_db );
End;
/

** write a stored procedure to a create user registration

** Create a user registration table with Tno, Customer Id, Accno,


User_name, Password, created date, created by

Validations :
-------------

-> Trans. No. should be generate automatically

-> User Name should not be repeated ( input )

-> Password should be start with an ALPHABET ( input )

-> Min. Length of Password is 6 characters

-> Enter Password and Confirm password should be same

-> Created date is today date automatically

-> Created by should be accept (Customer,Admin) ( input )

-> By default User Status is 1

-> User status should be accept either 1 / 0 ( input )

-> Status should be return (output)

step1 :

Table creation :
----------------

Create table bank_user_reg( Tno Number(4),


CId Number(10),
Accno Varchar2(10),
user_name Varchar2(15),
password varchar2(15),
Create_date timestamp,
created_by Varchar2(10),
user_status Number(1) check ( user_status in ( 1, 0
) )
);

step2 :
-------

-- create a sequence to generate tno automatically

Create sequence tno_seq


start with 1
increment by 1;
Step3 :
-------

-- Procedure for user registration

Create or replace procedure User_Registration_Proc( p_cid IN number,


p_accno IN varchar2,
p_user_name IN varchar2, --
king_sbi
p_password IN varchar2, --
king@123
p_cnf_password IN varchar2,
p_created_by IN varchar2,
p_status Out Varchar2
)
Is
Cnt Number;
Begin
Select count(*) Into cnt from bank_user_reg where user_name =
p_user_Name; -- if cnt=1 is exists, cnt=0 not exists
if cnt=1 then
p_status := 'UserName already Exists.....';
elsif ASCII( substr( p_password ,1,1) ) Not Between 65 and 90 and
ASCII( substr( p_password ,1,1) ) Not Between 97 and 122 then
p_status := 'Password should be start with an Alphabet..';
elsif length(p_password) <6 then
p_status := 'Min. Length of Password is 6 chars.';
elsif p_password != p_cnf_password then
p_status := 'Enter Password and Cnf. Passwords should be same..';
elsif p_created_by not in ( 'admin','customer') then
p_status := 'Invalid Role...';
else
Insert into bank_user_reg values( tno_seq.nextval, p_cid, p_accno,
p_user_name , p_password, sysdate, p_created_by, 1);
p_status := 'User Created Successfully...';
end if;
End User_Registration_Proc;
/

Calling procedure :
-------------------

Declare
v_status varchar2(100);
Begin
User_Registration_Proc( &cid, &accno, &username, &password,
&cnf_password, &created_by, v_status );
dbms_output.put_line( v_status );
End;
/

Enter value for cid: 11


Enter value for accno: 'sbi1'
Enter value for username: 'king_sbi'
Enter value for password: 'king@123'
Enter value for cnf_password: 'king@123'
Enter value for created_by: 'admin'
User Created Successfully...

PL/SQL procedure successfully completed.


SQL> /
Enter value for cid: 12
Enter value for accno: 'sbi2'
Enter value for username: 'sbi_kris'
Enter value for password: 'kris@786'
Enter value for cnf_password: 'kris@786'
Enter value for created_by: 'customer'
User Created Successfully...

PL/SQL procedure successfully completed.

SQL> select * from bank_user_reg;

TNO CID ACCNO USER_NAME PASSWORD


------ ------ ---------- --------------- ---------------
CREATE_DATE
CREATED_BY USER_STATUS
-------------------------------------------------------------------------
-- ---------- -----------
1 11 sbi1 king_sbi king@123
22-DEC-23 07.39.01.000000 AM
admin 1

2 12 sbi2 sbi_kris kris@786


22-DEC-23 07.39.42.000000 AM
customer 1

INVALID INPUTS :
-----------------

Declare
v_status varchar2(100);
Begin
User_Registration_Proc( &cid, &accno, &username, &password,
&cnf_password, &created_by, v_status );
dbms_output.put_line( v_status );
End;
/

Enter value for cid: 13


Enter value for accno: 'sbi3'
Enter value for username: 'scott_sbi'
Enter value for password: '123@scott'
Enter value for cnf_password: '123@scott'
Enter value for created_by: 'admin'
Password should be start with an Alphabet..

PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 13
Enter value for accno: 'sbi3'
Enter value for username: 'scott_sbi'
Enter value for password: 'king@123'
Enter value for cnf_password: '123@king'
Enter value for created_by: 'admin'
Enter Password and Cnf. Passwords should be same..
PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 13
Enter value for accno: 'sbi4'
Enter value for username: 'king_sbi'
Enter value for password: 'king@123'
Enter value for cnf_password: 'king@123'
Enter value for created_by: 'admin'
UserName already Exists.....

PL/SQL procedure successfully completed.

SQL> /
Enter value for cid: 13
Enter value for accno: 'sbi3'
Enter value for username: 'scott_sbi'
Enter value for password: 'scott'
Enter value for cnf_password: 'scott'
Enter value for created_by: 'admin'
Min. Length of Password is 6 chars.

PL/SQL procedure successfully completed.

** Write a stored procedure to input USERNAME & PASSWORD and return


Status

Create or replace procedure Login_Proc


( p_user_name IN bank_user_reg.user_name%type, -- king_sbi
p_password IN bank_user_reg.password%type, -- king
p_status OUT Varchar2
)
is
cnt Number;
Begin
Select count(1) Into cnt from bank_user_reg
where user_name = p_user_name
and
password = p_password;
if cnt=1 then
p_status := 'Login Successfully.';
else
p_status := 'Invalid UserName/Password';
end if;
End Login_Proc;
/

calling Procedure :
-------------------

Declare
v_status varchar2(100);
Begin
login_proc( &user_name, &password, v_status ); -- calling Procedure
dbms_output.put_line( v_status );
End;
/
Enter value for user_name: 'king_sbi'
Enter value for password: 'king@123'
Login Successfully.

PL/SQL procedure successfully completed.

SQL> /
Enter value for user_name: 'king_sbi'
Enter value for password: 'king'
Invalid UserName/Password

PL/SQL procedure successfully completed.

iii. IN OUT :
-------------

-> To declare any parameter as IN OUT, that parameter is taking INPUT


into Procedure and RETURN output through procedure

ex:-

Create or replace procedure INOUT_proc( X IN OUT NUMBER )


is
Begin
X := x * x * x;
End INOUT_proc;
/

calling Procedure :
*******************

declare
res number(10) := &res; -- 10
Begin
Inout_proc( res );
dbms_output.put_line( 'Result = ' || res );
end;
/

Enter value for res: 10


Result = 1000

PL/SQL procedure successfully completed.

STORED PROCEDURES WITH DEFAULT ARGUMENTS :


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

-> While calling the stored procedures if we are not passing value to
Parameters then by default
specified default values are taken.

-> Generally Default Parameters are placed in at the end of PARAMETERS


LIST

ex:-

-- stored procedure for to insert data into DEPT. table


Create or replace procedure dept_ins_Proc
( p_deptno dept.deptno%type,
p_dname dept.dname%type Default 'Unknown',
p_loc dept.loc%type Default 'Unknown'
)
is
Begin
Insert into dept values ( p_deptno, p_dname, p_loc );
dbms_output.put_line('Record Inserted.');
End dept_ins_proc;
/

calling procedure :
*******************

SQL> Exec dept_ins_Proc( 50, 'MATHS' );


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown

SQL> Exec dept_ins_Proc( 60, 'HYD' );


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Unknown
60 HYD Unknown

6 rows selected.

Note: In abvoe 2nd example, Dept.Name taken as 'HYD' and LOC taken as
'Unknown', because by default procedures calling according to
positions.

NOTATIONS :
-----------

-> Notation means, while calling the procedures to pass parameter


values according to corresponding Positions or by using Formal
arguments names, or both.
-> Procedures are supports three types of NOTATIONS

I. POSITIONAL NOTATIONS

II. NAMED NOTATIONS

III. MIXED NOTATIONS

I. POSITIONAL NOTATIONS :
-------------------------

-> While calling the procedures, to pass parameter values according


corresponding parameter positions is called as Positional Notations.

-> By default all procedures are calling by this methods only

ex:-

SQL> EXEC DEPT_INS_PROC( 50, 'MATHS', 'HYD' );


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD

II. NAMED NOTATIONS :


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

-> While calling the procedures, to pass parameter values by using


FORMAL ARGUMENT NAMES is called as NAMED NOTATIONS

ex:-

SQL> EXEC DEPT_INS_PROC( p_deptno=>60, p_loc=>'HYD', P_dname=>'ENG');


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD
60 ENG HYD

6 rows selected.
III. MIXED NOTATIONS :
----------------------

-> Both Positional and Named Notations

ex:-

SQL> EXEC DEPT_INS_PROC( 70, P_LOC=>'HYD');


Record Inserted.

PL/SQL procedure successfully completed.

SQL> SELECT * FROM DEPT;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS HYD
60 ENG HYD
70 Unknown HYD

7 rows selected.

** To see the created procedure Names

SQL> SELECT OBJECT_NAME FROM USER_OBJECTS WHERE OBJECT_TYPE='PROCEDURE';

OBJECT_NAME
-------------------------------------------------------------------------
-------------
INOUT_PROC
EMP_NETSAL_PROC
EMP_GRADE
GET_INFO
USER_REGISTRATION_PROC
LOGIN_PROC
ADD_PROC
MY_PROC
DEPT_INS
EMP_INCR_PROC
EMP_DEL
EMP_BONUS_PROC
DEPT_INS_PROC

13 rows selected.

** TO SEE THE PARTICULAR PROCEDURE BODY

SQL> SELECT TEXT FROM USER_SOURCE WHERE NAME='USER_REGISTRATION_PROC';


-- in WHERE clause Procedure name should be CAPITAL LETTERS

TEXT
-------------------------------------------------------------------------
---------------------------
procedure User_Registration_Proc( p_cid IN number,
p_accno IN varchar2,
p_user_name IN
varchar2, -- king_sbi
p_password IN
varchar2, -- king@123
p_cnf_password IN
varchar2,
p_created_by IN
varchar2,
p_status Out Varchar2
)
Is
Cnt Number;
Begin
Select count(*) Into cnt from bank_user_reg where user_name =
p_user_Name; -- if cnt=1 is exis
ts, cnt=0 not exists

if cnt=1 then
p_status := 'UserName already Exists.....';
elsif ASCII( substr( p_password ,1,1) ) Not Between 65 and 90 and
ASCII( substr( p_password ,1,1) ) Not Between 97 and 122 then
p_status := 'Password should be start with an Alphabet..';
elsif length(p_password) <6 then
p_status := 'Min. Length of Password is 6 chars.';
elsif p_password != p_cnf_password then
p_status := 'Enter Password and Cnf. Passwords should be same..';
elsif p_created_by not in ( 'admin','customer') then
p_status := 'Invalid Role...';
else
Insert into bank_user_reg values( tno_seq.nextval, p_cid, p_accno,
p_user_name , p_password, s
ysdate, p_created_by, 1);

p_status := 'User Created Successfully...';


end if;
End User_Registration_Proc;

28 rows selected.

** Dropping Procedures :
*************************

SYN:- DROP PROCEDURE <PROCEDURE_NAME>;

EX:- DROP PROCEDURE DEPT_INS_PROC;

II. USER DEFINED FUNCTIONS :


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

-> According to Client Requirements, developer write with his own


function name and own logic is called as
USER DEFINED FUNCTIONS

-> USER DEFINED FUNCTIONS are defined by USER


-> Function is a Self Contained Block

-> User defined fucntions should be return a value

-> User defind functions supports Parameters and Parameter Modes(IN,


OUT, INOUT )

-> User defined functions main advantages are.... :

i. Modularity

ii. Re-usability

iii. Improves the Performance

-> All created User Defined function Names are stored in USER_OBJECTS

-> All created User Defined Function Bodies are stored in USER_SOURCE
tables

Function Syntax :
-----------------

Create or replace function <function_name>


[( Arg1 Mode Datatype, Arg2 Mode Datatype,..)]
RETURN <datatype>
is
[<variable-declaration>;]
Begin
<exec-statements>;
[Exception
<exec-statatements>;]
End [<function_name>];
/

Ex:-

-- write a user defined function to find simple interest

SI = PTR/100;

Create or replace function Simple_Int( P Number, T Number, R Number )


Return Number
is
si Number;
Begin
si := P*T*(R/100);
return( si );
End Simple_Int;
/

Calling Function :
******************

on SQL prompt :
---------------

method 1:
---------
SQL> select Simple_int(1000,2,10) from dual;

SIMPLE_INT(1000,2,10)
---------------------
200

method 2 :
----------

SQL> variable res number;

SQL> exec :res := simple_int( 1000, 2, 10 );

PL/SQL procedure successfully completed.

SQL> print :res;

RES
------
200

method 3 :
----------

declare
result number;
begin
select simple_int(1000,2,10) into result from dual;
dbms_output.put_line('Simple Interest = ' || result );
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

method 4 :
----------

declare
result number;
begin
result := simple_int(1000,2,10);
dbms_output.put_line('Simple Interest = ' || result );
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

method 5 :
----------

begin
dbms_output.put_line('Simple Interest = ' || simple_int(1000,2,10));
End;
/

Simple Interest = 200

PL/SQL procedure successfully completed.

Ex2:-

-- Write a user defined function to input employee no. and return


corresponding employee experience

Create or replace function emp_exp


( p_empno IN Emp.empno%type )
return Number
is
expe Number;
Begin
select months_between(sysdate,hiredate)/12 Into expe from emp where
empno = p_empno;
return ( expe );
exception
when no_data_found then
return(-1);
End emp_exp;
/

SQL> select emp_exp(7788) from dual;

EMP_EXP(7788)
-------------
41.047

SQL> select emp_exp(9000) from dual;

EMP_EXP(9000)
-------------
-1

-- Function returns VARCHAR datatype

-- write a user defined function to input empno and return corresponding


employee DNAME

Create or replace function emp_dname( p_empno emp.empno%type )


Return Varchar2
is
v_dname dept.dname%type;
Begin
select dname into v_dname from dept where deptno=( select deptno
from emp where empno=p_empno ) ;
return ( v_dname ) ;
Exception
when no_data_found then
return( 'Employ Record Not Exists...' );
End Emp_Dname;
/

SQL> select emp_dname( 7788 ) from dual;


EMP_DNAME(7788)
-------------------------------------------------------------------------
---------------------------
RESEARCH

SQL> select emp_dname( 7521 ) from dual;

EMP_DNAME(7521)
-------------------------------------------------------------------------
---------------------------
SALES

SQL> select emp_dname( 7839 ) from dual;

EMP_DNAME(7839)
-------------------------------------------------------------------------
---------------------------
ACCOUNTING

SQL> select emp_dname( 9000 ) from dual;

EMP_DNAME(9000)
------------------------------------------------------------
Employ Record Not Exists...

Function returns BOOLEAN Datatype:


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

-- write a user defined function return EMPLOYEE Record Found or NOT

Create or replace function Emp_Find( p_empno emp.empno%type )


Return Boolean
is
cnt Number;
Begin
select count(1) into cnt from emp where empno = p_empno;
if cnt>0 then
return (true);
else
return( false );
end if;
End emp_find;
/

SQL> select emp_find(7788) from dual;


select emp_find(7788) from dual
*
ERROR at line 1:
ORA-06552: PL/SQL: Statement ignored
ORA-06553: PLS-382: expression is of wrong type

note: Above function returns TRUE(output) to SQL PROMPT but, SQL not
supported BOOLEAN datatype. So To call above function
in PL/SQL block we can call

Declare
flag boolean;
Begin
flag := emp_find( &empno ); -- here function is calling
if flag = true then
dbms_output.put_line( 'Employ Record Exists...');
else
dbms_output.put_line( 'Employ Record Not Exists...');
end if;
End;
/

Enter value for empno: 7788


Employ Record Exists...

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 7369
Employ Record Exists...

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 9000
Employ Record Not Exists...

PL/SQL procedure successfully completed.

-- we can call functions in IF condition

begin
if emp_find(&empno) then -- function is calling
dbms_output.put_line( 'Employ Record Exists...');
else
dbms_output.put_line( 'Employ Record Not Exists...');
end if;
End;
/

Enter value for empno: 7788


Employ Record Exists...

PL/SQL procedure successfully completed.

SQL> /
Enter value for empno: 9000
Employ Record Not Exists...

PL/SQL procedure successfully completed.

-- write a pl/sql block to insert data into CRIC INFO Table

table creation :
****************

Create table cric_info( cid varchar2(10),


fname varchar2(20),
mname varchar2(20),
lname varchar2(20)
);

ex:- Cric_info_proc( 'c1', 'ramesh sachin tendulkar' );

SQL> select substr('rama krishna',1,4) from dual;

SUBS
----
rama

SQL> select instr('rama krishna','k',1,1) from dual;

INSTR('RAMAKRISHNA','K',1,1)
----------------------------
6

SQL> select instr('rama krishna','a',1,1) from dual;

INSTR('RAMAKRISHNA','A',1,1)
----------------------------
2

SQL> select instr('rama krishna','a',1,2) from dual;

INSTR('RAMAKRISHNA','A',1,2)
----------------------------
4

Function for to return First Name :


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

Create or replace function Fname( cname varchar2 ) -- ramesh


sachin tendulkar
Return Varchar2
is
v_Fname cric_info.fname%type;
Begin
v_fname := substr(cname, 1, Instr(cname, ' ', 1 ,1 )-1 );
return( v_fname );
End fname;
/

Function for to return Last Name :


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

Create or replace function Lname( cname varchar2 ) -- ramesh sachin


tendulkar
return varchar2
is
v_Lname cric_info.Lname%type;
Begin
v_Lname := Substr( Cname, Instr(cname, ' ', -1, 1)+1 );
return( v_lname);
End Lname;
/
Function for to return Middle Name :
************************************

Create or replace function MName( Cname varchar2 ) -- sachin


Return Varchar2
is
v_Mname cric_info.mname%type;
Begin
v_Mname := Trim( Rtrim( Ltrim(cname, fname(cname) ), Lname(cname) ) );
return( v_Mname);
End Mname;
/

Procedure :
------------

Create or replace Procedure cric_info_proc( cid varchar2, cname varchar2


) -- 'c1', 'ramesh sachin tendulkar'
is
Begin
Insert into cric_Info values( cid, fname(cname),
mname(cname),lname(cname));
dbms_output.put_line('record inserted.');
End cric_info_proc;
/

SQL> EXEC CRIC_INFO_PROC('c1','ramesh sachin tendulkar');


record inserted.

PL/SQL procedure successfully completed.

SQL> EXEC CRIC_INFO_PROC('c2','virot kholi');


record inserted.

PL/SQL procedure successfully completed.

SQL> EXEC CRIC_INFO_PROC('c3','mahendar singh dhono');


record inserted.

PL/SQL procedure successfully completed.

SQL> EXEC CRIC_INFO_PROC('c4','siva rama krishna raju');


record inserted.

PL/SQL procedure successfully completed.

SQL> select * from cric_info;

CID FNAME MNAME LNAME


---------- -------------------- -------------------- --------------------
c1 ramesh sachin tendulkar
c2 virot kholi
c3 mahendar singh dhono
c4 siva rama krishna raju
** To see the created Function Names

SQL> select object_name from user_objects where object_type='FUNCTION';

OBJECT_NAME
-------------------------------------------------------------------------
---------------------------
SIMPLE_INT
EMP_EXP
EMP_DNAME
EMP_FIND
FNAME
LNAME
MNAME

7 rows selected.

** To see the created function body

SQL> select text from user_source where name='FNAME';

TEXT
-------------------------------------------------------------------------
---------------------------
function Fname( cname varchar2 ) -- ramesh sachin tendulkar
Return Varchar2
is
v_Fname cric_info.fname%type;
Begin
v_fname := substr(cname, 1, Instr(cname, ' ', 1 ,1 )-1 );
return( v_fname );
End fname;

8 rows selected.

** Dropping Functions

syn:- Drop Function <function_name>;

ex:- Drop Function Even_Odd;

Packages :
----------

-> Package is a collection of Variables, Cursors, Procedures &


Functions

-> Packages are used to Improves the performance while accessing sub-
programs(Procedures & Functions) from client location

-> Packages are used to improves the performance while retriving


programs

-> Packages are supports OOPs features like Function OverLoading, Data
Abstraction & Encapsulation

-> Packages are supports Procedure OverLoading also


-> Packages will not support any PARAMETERS and Will Not return any
values

-> All created package names are stored in USER_OBJECTS( pre-defined


table )

-> All created package bodies are stored in USER_SOURCE tables

PACKAGES ARE TWO PARTS :


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

I. PACKAGE SPECIFICATION

II. PACKAGE BODY

I. PACKAGE SPECIFICATION :
--------------------------

-> It contains declaration of Variables, Cursors, Procedures &


Functions

II. PACKAGE BODY :


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

-> It contains definitions of Package Specificaiton

-- Write a Package Program to find given employee netsal, and to return


grade

Package Specification :
***********************

Create or replace Package my_pack


is

Procedure emp_netsal( p_empno emp.empno%type );


Function emp_grade( p_empno emp.empno%type) return number;
End my_pack;
/

PACKAGE BODY :
**************

Create or replace Package Body my_pack


is

-- procedure body

Procedure emp_netsal( p_empno emp.empno%type )


is
v_netsal number;
begin
select sal + nvl(comm,0) into v_netsal from emp where empno=p_empno;
dbms_output.put_line(p_empno||' Employee Net Salary Rs.'||v_netsal);
Exception
when no_data_found then
raise_application_error(-20001, 'Employ Record Not Found.');
End Emp_Netsal;

-- Function Body

Function emp_grade( p_empno emp.empno%type) return number


is
v_grade Number;
Begin
select grade into v_grade from emp, salgrade
where sal between losal and hisal
and
empno = p_empno;
return( v_grade );
Exception
when no_data_found then
return( 0 );
End emp_grade;

End my_pack;
/

Calling Package Programs :


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

-- calling procedure

SQL> Exec my_pack.emp_netsal( 7369 );


7369 Employee Net Salary Rs.1200

PL/SQL procedure successfully completed.

SQL> Exec my_pack.emp_netsal( 9000 );


BEGIN my_pack.emp_netsal( 9000 ); END;

*
ERROR at line 1:
ORA-20001: Employ Record Not Found.
ORA-06512: at "ORA7AM.MY_PACK", line 14
ORA-06512: at line 1

-- Calling Function

SQL> select my_pack.emp_grade( 7369 ) from dual;

MY_PACK.EMP_GRADE(7369)
-----------------------
1

SQL> select my_pack.emp_grade( 7839 ) from dual;

MY_PACK.EMP_GRADE(7839)
-----------------------
5

SQL> select my_pack.emp_grade( 9000 ) from dual;

MY_PACK.EMP_GRADE(9000)
-----------------------
0

Function OverLoading :
**********************

-> Function Name is same and it supports different types of


Parameters/Arguments is called as Function Overloading

-> If no.of parameters are same then Corresponding parameters Datatype


should be different

Ex:-

Package Specification :
***********************

Create or replace package Fo_Pack


is
Function addval( x number, y number ) return number;
Function addval( x number, y number, z number ) return Number;
Function addval( str1 varchar2, str2 varchar2 ) return Varchar2;
End Fo_pack;
/

PACKAGE BODY :
**************

Create or replace package Body Fo_Pack


is
Function addval( x number, y number ) return number
is
Begin
Return( x + y );
End addval;

Function addval( x number, y number, z number ) return Number


is
Begin
Return( x + y + z );
End addval;

Function addval( str1 varchar2, str2 varchar2 ) return Varchar2


is
Begin
Return( str1 || ' ' || str2 );
End addval;

End Fo_pack;
/

SQL> select fo_pack.addval(100,200) from dual;

FO_PACK.ADDVAL(100,200)
-----------------------
300

SQL> select fo_pack.addval(100,200,500) from dual;

FO_PACK.ADDVAL(100,200,500)
---------------------------
800

SQL> select fo_pack.addval('naresh', 'it') from dual;

FO_PACK.ADDVAL('NARESH','IT')
-------------------------------------------------------------
naresh it

Procedure OverLoading :
-----------------------

-> Procedure Name is same and it supports different types of


Parameters/Arguments is called as Procedure Overloading

-> If no.of parameters are same then Corresponding parameters Datatype


should be different

Packages using CURSORS( REF CURSORS ) :


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

-- Write a package program to input dept no. and return corresponding


employee details

Create or replace package P1


is
Type r_cur is ref cursor;
status varchar2(100);
End P1;
/

note: to declare any variables,cursors,procedures & function inside


package specification
all are called as GLOBAL, these are we can access any where inside
the USER

Procedure for to return EMPLOY DETAILS and Procedure return Multiple


Records:
*************************************************************************
****

Create or replace Procedure get_details( p_deptno IN emp.deptno%type,


d_cur OUT p1.r_cur
)
is
Begin
OPen d_cur for select * from emp where deptno=p_deptno;
End get_details;
/
Calling Procedure :
-------------------

declare
v_cur P1.r_cur;
e emp%rowtype;
Begin
GET_DETAILS( &Deptno, v_cur ); -- calling procedure
loop
fetch v_cur into e;
exit when v_cur%notfound;
dbms_output.put_line( e.empno ||' '|| e.ename||' '||e.job||'
'||e.mgr||' '||e.hiredate||' '||e.sal||' '||e.deptno);
end loop;
close v_cur;
p1.status := 'Program Executed Successfully.';
dbms_output.put_line( p1.status );
End;
/

Enter value for deptno: 10


7782 CLARK MANAGER 7839 09-JUN-81 3185 10
7839 KING PRESIDENT 17-NOV-81 5500 10
7934 MILLER CLERK 7782 23-JAN-82 1950 10
Program Executed Successfully.

PL/SQL procedure successfully completed.

SQL> /
Enter value for deptno: 30
7499 ALLEN SALESMAN 7698 20-FEB-81 2080 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 30
7698 BLAKE MANAGER 7839 01-MAY-81 3705 30
7844 TURNER SALESMAN 7698 08-SEP-81 1950 30
7900 JAMES CLERK 7698 03-DEC-81 1425 30
Program Executed Successfully.

PL/SQL procedure successfully completed.

** to see the created package names

SQL> Select object_name from User_objects where object_type='PACKAGE';

OBJECT_NAME
-------------------------------------------------------------------------
---
MY_PACK
FO_PACK
P1

** To see the particular package body

SQL> select text from user_source where name='MY_PACK';

TEXT
-------------------------------------------------------------------------
---------------------------
Package my_pack
is

Procedure emp_netsal( p_empno emp.empno%type );


Function emp_grade( p_empno emp.empno%type) return number;
End my_pack;
Package Body my_pack
is

-- procedure body

Procedure emp_netsal( p_empno emp.empno%type )


is
v_netsal number;
begin
select sal + nvl(comm,0) into v_netsal from emp where empno=p_empno;
dbms_output.put_line(p_empno||' Employee Net Salary Rs.'||v_netsal);
Exception
when no_data_found then
raise_application_error(-20001, 'Employ Record Not Found.');
End Emp_Netsal;

-- Function Body

Function emp_grade( p_empno emp.empno%type) return number


is
v_grade Number;
Begin
select grade into v_grade from emp, salgrade
where sal between losal and hisal
and
empno = p_empno;
return( v_grade );
Exception
when no_data_found then
return( 0 );
End emp_grade;

End my_pack;

39 rows selected.

** Dropping Packages

Drop Package my_pack;

** Write a pl/sql block to Develop Following Modules

I. OPEN A NEW ACCOUNT (procedure)

II. VIEW ACCOUNT DETAILS (procedure)

III. DELETE ACCOUNT DETAILS(procedure)

IV. DEPOSIT AMOUNT(procedure)

V. WITHDRAW AMOUNT(procedure)

VI. TRANSFER AMOUNT (procedure)


VII. CHECK ACCOUNT BALANCE(function)

VIII. MINI STATEMENT(procedure)

IX. ACCOUNT STATEMENT(procedure)

Validations :
*************

bank_mas: Accno, cname, adddress, mobileno, mail id, account type,


opening date, & balance

bank_trans: Tno, SAccno, DAccno, Tdate, Ttype, & Tamount

I. OPEN A NEW ACCOUNT :


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

-> Account No. should be generate automatically

ex: sbi1, sbi2,.....

-> Customer name should be stored in as Capital letters

-> Mobile No. should not be accept duplicates

-> Mail id should not be accept duplicates

-> Account type should be accept S(savings), C(current a/c), or


AT(account transfer)

-> Account opening date will take system date automatically

-> Min. Account Opening Balance Rs.1000/-

II. VIEW ACCOUNT DETAILS :


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

-> To view account details by using ACCNO / MOBILENO

III. DELETE ACCOUNT DETAILS :


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

-> To delete account by using ACCNO

IV. DEPOSIT AMOUNT :


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

-> Once amount is deposited then balance should be update

V. WITHDRAW AMOUNT :
--------------------

-> Once amount is withdrawn then balance should be update

VI. TRANSFER AMOUNT :


----------------------
-> To Transfer amount from One account to Another Account

VII. CHECK ACCOUNT BALANCE :


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

-> To check account balance by using ACCNO / MOBILENO

VIII. MINI STATEMENT :


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

-> To generate latest/recent 5 transactions

IX. ACCOUNT STATEMENT :


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

-> To Generate account from two given dates

TABLE CREATIONS :
*****************

Bank_Mas :
----------

Create table Bank_mas( Acno Varchar2(10),


Cname Varchar2(10),
Address Varchar2(20),
Mobileno Number(10),
Mail_id Varchar2(20),
Acc_type Varchar2(2),
ODate Date,
Bal Number(8,2)
);

Bank_Trans :
************

Create Table Bank_Trans( Tno Number(4),


SAcno Varchar2(10),
DAcno Varchar2(10),
Tdate Date,
Ttype varchar2(2),
Tamt Number(8,2)
);

Sequence for to generate Acno Automatically :


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

Create Sequence acno_seq


start with 1
increment by 1;

*** Package Specification ****

Create or Replace Package Bank_Pack


is
-- Procedure Spec. for to open a new account
Procedure New_Acc( p_cname bank_mas.cname%type,
p_address bank_mas.address%type,
p_mobileno bank_mas.mobileno%type,
p_mail_id bank_mas.mail_id%type,
p_acc_type bank_mas.acc_type%type,
p_bal bank_mas.bal%type,
p_odate bank_mas.odate%type default sysdate );

-- Procedure spec. for to view account details by using ACNO

Procedure View_Acc( p_acno Bank_mas.acno%type);

-- Procedure spec. for to view account details by using MOBILENO

Procedure View_Acc( p_mobileno Bank_mas.mobileno%type);

-- Procedure spec. for to Delete Account Details

Procedure Del_Acc( p_acno bank_mas.acno%type);

-- Procedure spec. for to Deposite Aamount

Procedure Credit( p_sacno bank_trans.Sacno%type,


p_tamt bank_trans.tamt%type);

-- Procedure Spec. for to Withdraw Amount

Procedure Debit( p_sacno bank_trans.Sacno%type,


p_tamt bank_trans.tamt%type);

-- Procedure Spec. for to Transfer amount by using ACNOs.

Procedure Acc_Trans( p_sacno bank_trans.Sacno%type,


p_Dacno bank_Trans.Dacno%type,
p_Tamt Bank_Trans.Tamt%type );

-- Function Spec. for to CHECK ACCOUNT Balance by using ACNO

Function Chk_Bal( p_acno bank_mas.acno%type ) Return Number;

-- Function spec. for to CHECK ACCOUNT Balance by using MOBILENO

Function Chk_Bal ( p_mobileno Bank_mas.Mobileno%type) Return Number;

-- Procedure spec. for to Generate Mini Statement

Procedure Mini_Stat( p_SAcno Bank_trans.sacno%type );

-- Procedure Spec. for to generate Account Statement

Procedure Acc_Stat( p_Sacno Bank_trans.Sacno%type,


p_Sdate date,
p_Edate date );
End Bank_Pack;
/

*** PACKAGE BODY ***


Create or replace Package Body Bank_Pack
is

-- Procedure Body for to open a new account

Procedure New_Acc( p_cname bank_mas.cname%type,


p_address bank_mas.address%type,
p_mobileno bank_mas.mobileno%type, -- 9000994005
p_mail_id bank_mas.mail_id%type,
p_acc_type bank_mas.acc_type%type, -- C
p_bal bank_mas.bal%type,
p_odate bank_mas.odate%type default sysdate )
is
Mobile_cnt number;
Mail_cnt Number;
Begin
Select count(*) into mobile_cnt from bank_mas where Mobileno =
p_mobileno;
Select count(*) into mail_cnt from bank_mas where Mail_id = p_Mail_id;

if mobile_cnt>0 then
raise_application_error(-20001, 'Mobileno already registered.');
elsif mail_cnt>0 then
raise_application_error(-20002, 'e-mail already registered.');
elsif upper(p_acc_type) not in ( 'C','S') then
raise_application_error(-20003, 'Invaid Account Type!!!!');
elsif p_bal <1000 then
raise_application_error(-20004, 'Min. Account Opening Balance
Rs.1000/-');
else
Insert into bank_mas values( 'sbi'||(acno_seq.nextval),
upper(p_cname), p_address, p_mobileno,
p_mail_id, p_acc_type,
p_odate, p_bal);
dbms_output.put_line('Account created successfully.');
end if;
End New_Acc;

-- Procedure body for to view account details by using ACNO

Procedure View_Acc( p_acno Bank_mas.acno%type)


is
bm bank_mas%rowtype;
Begin
Select * into bm from bank_mas where acno = p_acno;
dbms_output.put_line('********* ACCOUNT DETAILS ************');
dbms_output.put_line('Account No : ' || bm.acno);
dbms_output.put_line('Customer Name : ' || bm.cname);
dbms_output.put_line('Address : ' || bm.address);
dbms_output.put_line('MobileNo : ' || bm.Mobileno);
dbms_output.put_line('Mail Id : ' || bm.mail_id);
dbms_output.put_line('Account Type : ' || bm.acc_type);
dbms_output.put_line('Opening Date : ' || bm.Odate);
dbms_output.put_line('Balance : ' || bm.Bal);
dbms_output.put_line('********* END OF THE RECCORD *********');
exception
when no_data_found then
raise_application_error(-20002, 'Invalid Account No!!!!');
End View_Acc;
-- Procedure Body for to view account details by using MOBILENO

Procedure View_Acc( p_mobileno Bank_mas.mobileno%type)


is
bm bank_mas%rowtype;
Begin
Select * into bm from bank_mas where mobileno = p_mobileno ;
dbms_output.put_line('********* ACCOUNT DETAILS ************');
dbms_output.put_line('Account No : ' || bm.acno);
dbms_output.put_line('Customer Name : ' || bm.cname);
dbms_output.put_line('Address : ' || bm.address);
dbms_output.put_line('MobileNo : ' || bm.Mobileno);
dbms_output.put_line('Mail Id : ' || bm.mail_id);
dbms_output.put_line('Account Type : ' || bm.acc_type);
dbms_output.put_line('Opening Date : ' || bm.Odate);
dbms_output.put_line('Balance : ' || bm.Bal);
dbms_output.put_line('********* END OF THE RECCORD *********');
exception
when no_data_found then
raise_application_error(-20002, 'Invalid Mobile No!!!!');
End View_Acc;

-- Procedure spec. for to Delete Account Details

Procedure Del_Acc( p_acno bank_mas.acno%type)


is
Begin
Delete from Bank_mas where Acno = p_acno;
if sql%found then
dbms_output.put_line('Record Deleted');
else
raise_application_error(-20003, 'Invalid Account No.!!!!!');
end if;
End Del_Acc;

-- Procedure Body for to Deposit Amount

Procedure Credit( p_sacno bank_trans.Sacno%type, -- sbi10


p_tamt bank_trans.tamt%type) -- -1000
is
Begin
update bank_mas set bal = bal + p_tamt where acno = p_sacno;
dbms_output.put_line('amt. credited');
End Credit;

-- Procedure body for to Withdraw Amount

Procedure Debit( p_sacno bank_trans.Sacno%type,


p_tamt bank_trans.tamt%type)
is
Begin
update bank_mas set bal = bal - p_tamt where acno = p_sacno;
dbms_output.put_line('amt. debited');
End Debit;

-- Procedure body for to Transfer amount by using ACNOs.


Procedure Acc_Trans( p_sacno bank_trans.Sacno%type,
p_Dacno bank_Trans.Dacno%type,
p_Tamt Bank_Trans.Tamt%type )
is
Begin
debit(p_sacno, p_tamt); -- debit procedure is calling
Credit(p_dacno, p_tamt); -- credit procedure is calling
dbms_output.put_line('Amt. Transfer Successfully.');
End Acc_Trans;

-- Function Body for to CHECK ACCOUNT Balance by using ACNO

Function Chk_Bal( p_acno bank_mas.acno%type ) Return Number


is
v_bal Number;
Begin
select bal into v_bal from bank_mas where acno = p_acno;
return( v_bal );
exception
when no_data_found then
return(-1);
End Chk_Bal;

-- Function Body for to CHECK ACCOUNT Balance by using MOBILENO

Function Chk_Bal ( p_mobileno Bank_mas.Mobileno%type) Return Number


is
v_bal Number;
Begin
select bal into v_bal from bank_mas where mobileno = p_mobileno;
return( v_bal );
exception
when no_data_found then
return(-1);
End Chk_Bal;

-- Procedure body for to Generate Mini Statement

Procedure Mini_Stat( p_SAcno Bank_trans.sacno%type )


is
Cursor Mini_cur is Select Sacno, Tdate, Ttype, Tamt from ( select
Sacno, Tdate, Ttype, Tamt from bank_trans
where SAcno =
p_SAcno order by tdate desc )
where
rownum <=5;
bt mini_cur%rowtype;
Begin
open mini_cur;
dbms_output.put_line('***** MINI STATEMENT *****');
Loop
Fetch mini_cur into bt;
exit when mini_cur%notfound;

dbms_output.put_line(rpad(bt.Sacno,10)||rpad(bt.Tdate,10)||rpad(bt.Ttype,
10)||rpad(bt.Tamt,10));
End Loop;
Close Mini_cur;
dbms_output.put_line('***** END OF THE RECORDS *****');
End Mini_stat;
-- Procedure body for to generate Account Statement

Procedure Acc_Stat( p_Sacno Bank_trans.Sacno%type,


p_Sdate date,
p_Edate date )
is
Cursor acc_cur is select * from bank_trans where trunc(tdate)
between trunc(p_Sdate) and trunc(p_Edate)
and
Sacno = p_Sacno;
ac acc_cur%rowtype;
Begin
open acc_cur;
dbms_output.put_line('***** ACC STATEMENT *****');
Loop
fetch acc_cur into ac;
exit when acc_cur%notfound;
dbms_output.put_line(
rpad(ac.Sacno,10)||rpad(ac.Dacno,10)||rpad(ac.tdate,10)||rpad(ac.ttype,10
)||rpad(ac.tamt,10));
End Loop;
dbms_output.put_line('***** END OF THE RECORDS *****');
End Acc_stat;

End Bank_Pack;
/

Inserting data into bank_trans table :


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

Insert into bank_trans values(1,'sbi1',null, '24-dec-23', 'd', 1000 );


Insert into bank_trans values(2,'sbi2',null, '24-dec-23', 'w', 200 );
Insert into bank_trans values(3,'sbi1',null, '25-dec-23', 'w', 400 );
Insert into bank_trans values(4,'sbi1',null, '25-dec-23', 'd', 600 );
Insert into bank_trans values(5,'sbi2',null, '27-dec-23', 'd', 500 );
Insert into bank_trans values(6,'sbi1',null, '28-dec-23', 'd', 100 );
Insert into bank_trans values(7,'sbi1',null, '31-dec-23', 'w', 300 );
Insert into bank_trans values(8,'sbi1',null, '2-Jan-24', 'd', 1500 );
Insert into bank_trans values(9,'sbi1',null, '2-Jan-24', 'w', 200 );

commit;

SQL> select * from bank_trans;

TNO SACNO DACNO TDATE TT TAMT


------ ---------- ---------- --------- -- ------
1 sbi1 24-DEC-23 d 1000
2 sbi2 24-DEC-23 w 200
3 sbi1 25-DEC-23 w 400
4 sbi1 25-DEC-23 d 600
5 sbi2 27-DEC-23 d 500
6 sbi1 28-DEC-23 d 100
7 sbi1 31-DEC-23 w 300
8 sbi1 02-JAN-24 d 1500
9 sbi1 02-JAN-24 w 200

9 rows selected.
EXECUTE PACKAGE PROGRAME:
-----------*************

To Create a New Account :


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

SQL> Exec Bank_pack.new_acc( 'king', 'hyd',


9000994005,'[email protected]','s',1500 );
Account created successfully.

PL/SQL procedure successfully completed.

SQL> Exec Bank_pack.new_acc( 'scott', 'sec',


9000994006,'[email protected]','c',2400 );
Account created successfully.

PL/SQL procedure successfully completed.

SQL> set num 10;


SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 1500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

View Account Details :


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

SQL> Exec bank_pack.view_acc('sbi1');


********* ACCOUNT DETAILS ************
Account No : sbi1
Customer Name : KING
Address : hyd
MobileNo : 9000994005
Mail Id : [email protected]
Account Type : s
Opening Date : 04-JAN-24
Balance : 1500
********* END OF THE RECCORD *********

PL/SQL procedure successfully completed.

Delete Account Details :


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

SQL> exec bank_pack.del_acc('sbi1');


Record Deleted

PL/SQL procedure successfully completed.

Deposit Amount :
----------------

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 1500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

SQL> exec bank_pack.credit('sbi1',1000);


amt. credited

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 2500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

Withdraw Amt. :
---------------

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 2500
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

SQL> exec bank_pack.debit('sbi1',200);


amt. debited

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 2300
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2400

Tamount Transfer :
******************

SQL> Exec bank_pack.acc_trans('sbi1','sbi2',500);


amt. debited
amt. credited
Amt. Transfer Successfully.

PL/SQL procedure successfully completed.

SQL> select * from bank_mas;

ACNO CNAME ADDRESS MOBILENO MAIL_ID


AC ODATE BAL
---------- ---------- -------------------- ---------- -------------------
- -- --------- ----------
sbi1 KING hyd 9000994005 [email protected]
s 04-JAN-24 1800
sbi2 SCOTT sec 9000994006 [email protected]
c 04-JAN-24 2900

To Check Account Balance by using ACNO:


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

SQL> select bank_pack.chk_bal('sbi1') from dual;

BANK_PACK.CHK_BAL('SBI1')
-------------------------
1800

To Check Account Balance by using MOBILENO:


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

SQL> select bank_pack.chk_bal(9000994006) from dual;

BANK_PACK.CHK_BAL(9000994006)
-----------------------------
2900

MINI STATEMENT :
****************
SQL> Exec Bank_pack.mini_stat('sbi1');

***** MINI STATEMENT *****


sbi1 02-JAN-24 d 1500
sbi1 02-JAN-24 w 200
sbi1 31-DEC-23 w 300
sbi1 28-DEC-23 d 100
sbi1 25-DEC-23 w 400
***** END OF THE RECORDS *****

PL/SQL procedure successfully completed.

Account Statement :
*******************

SQL> Exec Bank_pack.Acc_stat('sbi1','01-dec-23',sysdate);


***** ACC STATEMENT *****
sbi1 24-DEC-23 d 1000
sbi1 25-DEC-23 w 400
sbi1 25-DEC-23 d 600
sbi1 28-DEC-23 d 100
sbi1 31-DEC-23 w 300
sbi1 02-JAN-24 d 1500
sbi1 02-JAN-24 w 200
***** END OF THE RECORDS *****

PL/SQL procedure successfully completed.

TRIGGERS :
**********

-> A Set of Pl/Sql statements stored in DB permanently and


automatically executed whenever EVENT raising
statement is performed.

-> Triggers are executed WHENEVER DML operations(Events) are performed

-> Triggers are executed when the tables are manipulated by other users
or by other application s/w tools

-> Triggers are used for AUDITING Purpose

-> Triggers are used to restrict User Defined Conditions or Business


Rules

-> All Created Trigger Names are stored in USER_TRIGGERS/USER_OBJECTS (


system table )

-> All Created Trigger Bodies are stored in USER_SOURCE ( system table
)

Trigger Parts :
***************

i. Trigger Event :
------------------

-> It indicates when to activate/execute the trigger

-> Trigger Events are...

a. Before Insert b. Before Update c. Before Delete

d. After Insert e. After Update f. After Delete

ii. Trigger Type :


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

-> It indicates type of the Trigger

-> There are two types of Triggers

a. Row Level Triggers

b. Statement Level Triggers


iii. Trigger Restriction :
-------------------------

-> It is used to stop automatic execution of code

iv. Trigger Body :


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

-> A set of PL/SQL statements

Trigger syn:-
*************

Create or replace Trigger <Trigger_Name>


Before/After INSERT or UPDATE or DELETE -- i
[of Columns] ON <table_name>
[For Each Row] -- ii
[When <condition>] -- iii
[Declare
<variable-declaration>;]
Begin
<exec-statements>; -- iv
[Exception
<exec-statements>;]
End;
/

** To perform any DML operations on DB table first Data will be stored in


ROLLBACK segment

dept: -- step 3
-----

deptno dname loc


------ ----- -----
50 Maths Hyd

rollback segment: -- step 2


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

:deptno=50
:dname=Maths
:loc=Hyd

sql> Insert Into Dept values( 50, 'Maths', 'Hyd' ); -- step 1

** Triggers are supports two types of Access Specifiers

i. New ii. Old


-> these access specifier are supported in preceeding ROLLBACK SEGMENT
Columns

ex: :NEW.DEPTNO = 50, :NEW.DNAME=Maths, :NEW.LOC=Hyd

Before Insert
Before Update
Before Delete :NEW.
After Insert
After Update

After Insert
After Update :OLD.
After Delete

UPDATE EMP SET SAL = SAL + 100 WHERE EMPNO=7788;

Ex:-

-- write a trigger program, while inserting data into dept. table to


change DEPT. NAME with Capital letters automatically

dept :
------

deptno dname loc -- step 4


------ ------ ----
50 MATHS Hyd

rollback segment: -- step 2


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

:deptno=50
:dname=MATHS
:loc=Hyd

sql> Insert Into Dept values( 50, 'maths', 'Hyd' ); -- step 1

Create or replace trigger Dept_Trig -- step 3


Before Insert
ON DEPT
for each row
Begin
:new.dname := upper(:new.dname);
End;
/

Trigger created.
SQL> Insert Into dept values( 50, 'maths', 'Hyd');

1 row created.

SQL> select * from dept;

DEPTNO DNAME LOC


------ -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
50 MATHS Hyd

-- write a trigger program, to RAISE ERROR if Updating Salary is <


Existing Salary

7788 SCOTT ANALYST 7566 09-DEC-82 3900 20

rollback segment:
-----------------

:old.empno=7788 :new.empno = 7788


:old.ename=scott :new.sal = 2500
:old.sal=3900
.
.
:old.deptno=20

sql> Update emp Set sal = 2500 where empno = 7788; -- step 2

Trigger :
---------

Create or replace trigger emp_update_trig -- step 3


Before Update ON EMP
for each row
Begin
if :new.sal < :old.sal then -- 4000 < 3900
raise_application_error(-20001, 'Updating Salary should be >
Existing Salary');
end if;
End;
/

Trigger created.

SQL> Update emp set sal = 2500 where empno=7788;


Update emp set sal = 2500 where empno=7788
*
ERROR at line 1:
ORA-20001: Updating Salary should be > Existing Salary
ORA-06512: at "ORA7AM.EMP_UPDATE_TRIG", line 3
ORA-04088: error during execution of trigger 'ORA7AM.EMP_UPDATE_TRIG'
SQL> Update emp set sal = 4500 where empno=7788;

1 row updated.

note: In Triggers to display ERROR MESSAGES then we should be use


RAISE_APPLICATION_ERROR

Ex 3:-

-- Write a trigger program to take employee records backup for


Auditing Purpose

You might also like