0% found this document useful (0 votes)
4 views180 pages

Oracle Notes

The document provides a comprehensive overview of databases, including definitions of data, information, database management systems (DBMS), relational databases (RDBMS), and object-relational databases (ORDBMS). It outlines the database development life cycle, features of RDBMS, SQL usage, and various data types in Oracle, along with examples of creating users and tables. Additionally, it discusses the evolution of DBMS, client/server architecture, and how to connect to and manage an Oracle database.

Uploaded by

vineelap742
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views180 pages

Oracle Notes

The document provides a comprehensive overview of databases, including definitions of data, information, database management systems (DBMS), relational databases (RDBMS), and object-relational databases (ORDBMS). It outlines the database development life cycle, features of RDBMS, SQL usage, and various data types in Oracle, along with examples of creating users and tables. Additionally, it discusses the evolution of DBMS, client/server architecture, and how to connect to and manage an Oracle database.

Uploaded by

vineelap742
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 180

DATA :-

--------

=> Data represents unprocessed and unorganized raw facts that doesn't carray
any mearning

INFORMATION :-
---------------

=> processed and organized data is called information

DATABASE :-
-----------

=> DB is a organized collection of interrelated data , For example a


bank db stores data related to customers,accounts and transactions etc
and a univ db stores data related to students,courses and faculty etc

Types of Databases :-
-----------------------

1 OLTP DB (online transaction processing)


2 OLAP DB (online analytical processing)

=> organizations uses OLTP DB for day-to-day transactions and OLAP for analysis.
=> OLTP for running business and OLAP for analyzing business.
=> day-to-day operations on db includes

C CREATE
R READ
U UPDATE
D DELETE

DBMS :-
--------

=> DBMS stands for Database Management System.


=> It is a software used to create and to manage database.
=> It is an interface between user and database.

USER--------------DBMS------------------DB

Evolution of DBMS :-
--------------------

1960 FMS (FILE MGMT SYSTEM)

1970 HDBMS (HIERARCHICAL DBMS)


NDBMS (NETWORK DBMS)

1980 RDBMS (RELATIONAL DBMS)

1990 ORDBMS (OBJECT RELATIONAL DBMS)

RDBMS :-
--------
=> RDBMS concepts are introduced by E.F.CODD
=> E.F.CODD introduced 12 rules called codd rules
=> a db that supports all 12 rules called perfect rdbms

Information Rule :-
--------------------

=> according to information rule data must be organized in tables i.e. rows and
columns

EX :-
CUST
CID NAME CITY => columns / fields / attributes
10 SACHIN MUM
11 RAHUL DEL
12 VIJAY HYD => row / record / tuple

DATABASE = COLLECTION OF TABLES


TABLE = COLLECTION OF ROWS & COLS
ROW = COLLECTION OF FIELD VALUES
COLUMN = COLLECTION OF VALUES BELONGS TO ONE FIELD

=> Every table must contain primary key to uniquely identify the records

Ex :- ACCNO,EMPID,AADHARNO,PANNO,VOTERID

RDBMS features :-
------------------

1 easy to access and manipulate data


2 less redundency (duplication of data)
3 more security
4 gurantees data quality / data consistency / data integrity
5 supports data sharing
6 supports transactions

RDBMS softwares :-
-------------------

ORACLE from oracle corp


MYSQL from oracle corp
SQL SERVER from microsoft
DB2 from ibm
RDS from amazon

ORDBMS :-
----------

=> Object Relational DBMS


=> It is combination of RDBMS & OOPS

ORDBMS = RDBMS + OOPS (REUSABILITY)

=> RDBMS doesn't support reusability but ORDBMS supports reusability

ORDBMS softwares :-
--------------------
ORACLE upto 7 ver RDBMS
ORACLE from 8 ver ORDBMS
POSTGRESQL

18-JUL-24

DB Development Life Cycle :-


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

Analysis
Design
Develop
Test
Deploy/Implement
Maintain

Design :-
-----------

=> Designing db means designing tables.


=> DB is designed by DB Designers/Architects
=> DB is designed by using

1 ER Model (Entity Relationship)


2 Normalization

Development :-
--------------

=> DB is developed by DB Developers & DBAs (DB Admin)


=> DB is developed by using any rdbms software like oracle.

Developer DBA

creating tables installation of oracle


creating views creating database
creating synonyms creating userids
creating sequences db backup & restore
creating indexes db export & import
creating procedures db upgradation & migration
creating functions performance tuning
creating packages
creating triggers
writing queries

oracle 12c ver ===> oracle 21c => db upgradation


mysql ====> oracle => db migration

Testing :-
---------

=> DB is tested by QA team (Quality Assurance) by using

1 manual
2 automation using a tool called selenium

Deployment / Implemenation :-
-----------------------------

=> moving db from DEV server to PROD server is called implementation


=> after moving db to PROD server end users can use db for day-to-day operations

summary :-

what is db ?
what is dbms ?
what is rdbms ?
what is ordbms ?
what is db development life cycle ?

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

ORACLE
=======

=> oracle is basically a rdbms product and also supports ordbms features
and used to create and to manage database.

=> oracle is used for db development and administration.

versions of oracle :-
---------------------

2,3,4,5,6,7,8i,9i,10g,11g,12c,18c,19c,21c,23c

i => internet
g => grid
c => cloud

=> from 8 onwards suffix "i" is added because oracle supports internet
applications

=> GRID means collection of servers , from 10g onwards oracle db can be
accesssed through mutliple servers. If one server is down we can
access db through another server. so grid improves availability.

=> from 12c onwards oracle db can be deployed in

1 ON PREMISES
2 ON CLOUD

=> In " ON PREMISES " db is deployed in the server managed by client.

=> In " ON CLOUD " db is deployed in the server managed by cloud service provider
like amazon,microsoft,google,oracle etc.

CLIENT / SERVER Architecture :-


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

SERVER :-
---------

=> server is a system where oracle is installed and running


=> inside the server oracle manages two memories
1 DB
2 INSTANCE

=> DB is created in hard disk and acts as permanent storage


=> INSTANCE is created in ram and acts as temporary storage

CLIENT :-
------------

=> client is also a system from where users can

1 connects to server
2 submit requests to server
3 receives response from server

client tool :-

1 SQLPLUS (COMMAND BASED)


2 SQL DEVELOPER (GUI)

20-jul-24

SQL :-
-------

=> SQL stands for structured query language.


=> a language used to communicate with oracle.
=> user communicates with oracle by sending commands called queries.
=> a query is a command/question/instruction submitted to oracle
to perform some operation over db.
=> SQL is originally introduced by IBM and initial name of this
language was "sequel" and later it is renamed to SQL.
=> SQL is common to all relational databases.

USER----SQLPLUS--------------SQL---------ORACLE---------DB

USER----MYSQLWORKBENCH-------SQL----------MYSQL---------DB

USER----SSMS----------------SQL-----------SQL SERVER----DB

USER---PGADMIN--------------SQL-----------POSTGRESQL------DB

=> based on operations over db SQL is categorized into following


sublanguages.

DDL (DATA DEFINITION LANG)


DML (DATA MANIPULATION LANG)
DQL (DATA QUERY LANG)
TCL (TRANSACTION CONTROL LANG)
DCL (DATA CONTROL LANG)

SQL

DDL DML DQL TCL DCL

CREATE INSERT SELECT COMMIT GRANT


ALTER UPDATE ROLLBACK REVOKE
DROP DELETE SAVEPOINT
TRUNCATE INSERT ALL
RENAME MERGE
FLASHBACK
PURGE

DATA & DATA DEFINITION :-


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

EMPID ENAME SAL => DATA DEFINITION / METADATA


100 A 6000 => DATA

22-jul-24

SCHEMA :-
----------

=> a user in oracle db is called schema.


=> objects created by user are called schema objects.

SERVER
DATABASE
USER (SCHEMA)
TABLES (SCHEMA OBJECTS)
DATA

SERVER
ORCL
SYS / MANAGER (DBA)
SYSTEM / MANAGER (DBA)

How to connect to oracle :-


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

=> to connect to oracle open sqlplus and enter username and password

USERNAME :- SYSTEM
PASSWORD :- MANAGER

OR

USERNAME :- SYSTEM / MANAGER

CREATING USER/SCHEMA/ACCOUNT IN DATABASE :-


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

=> only DBAs are having permissions to create new user

STEP 1 :- connect as DBA

USERNAME :- SYSTEM / MANAGER

STEP 2 :- creating user

syn :-

CREATE USER <name> IDENTIFIED BY <pwd>


DEFAULT TABLESPACE USERS
QUOTA UNLIMINTED ON USERS ;
Ex :-

SQL>CREATE USER BATCH430 IDENTIFIED BY ORACLE


DEFAULT TABLESPACE USERS
QUOTA UNLIMITED ON USERS ;

STEP 3 :- granting permissions to user

SQL>GRANT CONNECT,RESOURCE TO BATCH430 ;

CONNECT => to connect to db


RESOURCE => to create objects like tables
DBA => all permissions

SQL>GRANT DBA TO BATCH430 ;

Changing password :-
--------------------

=> both user & dba can change password

BY USER :- (BATCH430/ORACLE)
----------

SQL>PASSWORD ;
enter old password :- ORACLE
enter new password :- NARESH
retype new password :- NARESH
password changed

BY DBA :- (SYSTEM/MANAGER)
---------

SQL>ALTER USER BATCH430 IDENTIFIED BY TIGER ;

Droping user :-
---------------

=> only DBAs are having permissions to drop user

syn :- DROP USER <NAME> ;

ex :-

SQL>DROP USER BATCH430 ;

DOWNLOAD & INSTALL :-


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

DOWNLOAD :-
----------

https://www.oracle.com/in/database/technologies/xe-downloads.html

STEP BY STEP INSTALLATION :-


-------------------------------
https://www.programsbuzz.com/article/install-oracle-xe-21c-windows-10

SERVER
ORCL
SYS
SYSTEM
BATCH430
NARESH

23-jul-24

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

=> a datatype specifies

1 type of the data allowed in a column


2 amount of memory allocated for column

DATATYPES

CHAR NUMERIC DATE BINARY

ASCII UNICODE NUMBER(P) DATE BFILE


NUMBER(P,S) TIMESTAMP BLOB
CHAR NCHAR
VARCHAR2 NVARCHAR2
LONG NCLOB
CLOB

CHAR(SIZE) :-
-------------

=> allows character data upto 2000 chars


=> it is recommended for fixed length char columns

ex :- NAME CHAR(10)

S A C H I N - - - -
wasted

R A V I - - - - - -
wasted

=> in char datatype extra bytes are wasted , so char is not recommended
for variable length fields and char is recommended for fixed length fields.

ex :- GENDER CHAR(1)

M
F

STATE_CODE CHAR(2)

AP
TG
COUNTRY_CODE CHAR(3)

IND
USA

VARCHAR2 :-
------------

=> allows character data upto 4000 chars


=> it is recommended for variable length fields

ex :- NAME VARCHAR2(10)

SACHIN - - - -
released

=> in varchar2 extra bytes are released

NOTE :-

=> CHAR/VARCHAR2 allows ascii chars (256 chars) that includes a-z,A-Z,0-9,
special chars i.e. CHAR/VARCHAR2 allows alphanumeric data.

ex :- PANNO CHAR(10)
VEHNO CHAR(10)
EMAILID VARCHAR2(20)

LONG :-
-------

=> allows character data upto 2GB.

EX :- REVIEW LONG

CLOB :-
--------

=> CLOB stands for character large object


=> allows character data upto 4GB.

ex :- TEXT CLOB

NCHAR / NVARCHAR2 / NCLOB :- ( N => National)


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

=> allows unicode chars (65536 chars) that includes all ascii chars and
chars belongs to different languages.

NUMBER(P) :-
------------

=> allows numbers without decimal (integers)


=> number can be upto 38 digits

ex :- EMPID NUMBER(4)

10
100
1000
10000 => NOT ALLOWED

PHONE NUMBER(10)

AADHARNO NUMBER(12)

ACCNO NUMBER(11)

NUMBER(P,S) :-
---------------

=> allows numbers with decimal (float)

P => precision => total no of digits allowed


S => scale => no of digits allowed after decimal

ex :- 1 SALARY NUMBER(7,2)

5000
5000.55
50000.55
500000.55 => NOT ALLOWED

5000.5678 => ALLOWED => 5000.57


5000.5643 => ALLOWED => 5000.56

NOTE :- if before decimal exceeds number is not accepted


if after decimal exceeds number is rounded

2 SAVG NUMBER(5,2)

3 BALANCE NUMBER(15,4)

DATE :-
-------

=> DATE datatype allows date & time


=> time is optional , if not entered oracle stores 12:00AM
=> default date format in oracle is DD-MON-YY / YYYY
=> date must be between 1 JAN 4712 BC TO 31 DEC 9999 AD

EX :- DOB DATE

10-OCT-03 => 10-OCT-2003


15-MAR-98 => 15-MAR-2098
15-MAR-1998 => 15-MAR-1998

=> a date occupies 7 bytes

input :- DD-MON-YYYY

stores :- DD MM YYYY HH MI SS
1 1 2 1 1 1

TIMESTAMP :-
--------------
=> TIMESTAMP allows date,time and also milliseconds

ex :- T TIMESTAMP

24-JUL-24 17:07:20.123
--------- ------- ---
DATE TIME MS

=> timestamp takes 9 to 13 bytes depends on milliseconds

BINARY :-
---------

=> binary types are used for storing multimedia objects like audio,video,images
=> oracle supports 2 binary types

1 BFILE (Binary File)


2 BLOB (Binary Large object)

=> BFILE is called external lob because lob is stored outside db but db
stores path

=> BLOB is called internal lob because lob is stored inside db.

CREATING TABLES :-
-------------------

CREATE TABLE <tabname>


(
COLNAME DATATYPE(SIZE),
COLNAME DATATYPE(SIZE),
------------------
);

Rules :-
--------

1 name should start with alphabet


2 name should not contain spaces & special chars but allows _ $ #
3 name can be upto 128 chars
4 table can have upto 1000 cols
5 no of rows unlimited

EX :- 123CUST invalid
CUST 123 invalid
CUST*123 invalid
CUST_123 valid

Example :-

=> create table with following structure ?

EMP
EMPID ENAME JOB SAL HIREDATE DEPTNO

CREATE TABLE EMP


(
EMPID NUMBER(4),
ENAME VARCHAR2(10),
JOB VARCHAR2(10),
SAL NUMBER(7,2),
HIREDATE DATE,
DEPTNO NUMBER(2)
);

=> above command created table structure / defintion / metadata that


includes columns , datatype and size.

TABLE = STRCTURE (COLS) + DATA (ROWS)

DESC :- (DESCRIBE)
--------

=> command used to see the table structure

syntax :- DESC <tabname> ;

example :- SQL>DESC EMP

EMPID NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(10)
SAL NUMBER(7,2)
HIREDATE DATE
DEPTNO NUMBER(2)

INSERTING DATA INTO TABLE :-


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

=> "INSERT" command is used to insert data into table.


=> INSERT command creates new row.
=> we can insert

1 single row
2 multiple rows

INSERTING SINGLE ROW :-


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

INSERT INTO <tabname> VALUES(v1,v2,v3,-------) ;

Ex :-

SQL>INSERT INTO EMP VALUES(100,'SACHIN','CLERK',5000,'25-JUL-24',20);


SQL>INSERT INTO EMP VALUES(101,'ARVIND','MANAGER',8000,SYSDATE,10);

=> above insert commands inserted data into instance (ram) which is
temporary storage , to save this data permanently execute commit command.

SQL>COMMIT;

=> In normal exit operations are saved and in abnormal exit operations are
not saved.

SQL>EXIT ; => normal exit


CLOSING SQLPLUS WINDOW => abnormal exit

INSERTING MULTIPLE ROWS :-


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

=> INSERT comamnd can be executed multiple times with different values
by using variables prefixed with "&".

ex :-

SQL>INSERT INTO EMP VALUES(&EMPID,&ENAME,&JOB,&SAL,&HIREDATE,&DEPTNO) ;

Enter value for empid: 103


Enter value for ename: 'VIJAY'
Enter value for job: 'ANALYST'
Enter value for sal: 6000
Enter value for hiredate: '5-OCT-19'
Enter value for deptno: 20

SQL> /
Enter value for empid: 104
Enter value for ename: 'SATISH'
Enter value for job: 'CLERK'
Enter value for sal: 4000
Enter value for hiredate: '25-JAN-21'
Enter value for deptno: 20

INSERTING NULLS :-
------------------

=> NULL means blank or empty


=> it is not equal to 0 or space
=> nulls can be inserted in two ways

method 1 :-
-----------

INSERT INTO EMP VALUES(105,'RAVI','',NULL,'14-MAR-18',10);

method 2 :-
-----------

INSERT INTO EMP(EMPID,ENAME,HIREDATE,DEPTNO) VALUES(106,'AJAY',SYSDATE,30);

remaining two fields job,sal are automatically filled with NULLs

Assignment :-
--------------

=> create table for storing bank customers data ?

CUST
CUSTID NAME GENDER DOB EMAILID PHONE ADDR STATE AADHARNO PANNO

DISPLAYING DATA :-
-------------------

=> "SELECT" command is used to display data from table.


=> we can display all rows and all columns
=> we can display specific rows and specific columns

Syntax :-

SELECT COLUMNS / * FROM TABNAME ;

SQL = ENGLISH
QUERIES = SENTENCES
CLAUSES = WORDS

FROM clause => specify tablename


SELECT clause => specify column names
* => all columns

Examples :-

=> display employee names and salaries ?

SQL>SELECT ENAME,SAL FROM EMP ;

=> display employee names,jobs,hiredates ?

SQL>SELECT ENAME,JOB,HIREDATE FROM EMP ;

=> display all the data from emp ?

SQL>SELECT * FROM EMP ;

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

1 Arithmetic Operators => + - * /


2 Relational Operators => > >= < <= = <> !=
3 Logical Operators => AND OR NOT
4 Special Operators => BETWEEN
IN
LIKE
IS
ANY
ALL
EXISTS
PIVOT
5 Set Operators => UNION
UNION ALL
INTERSECT
MINUS

WHERE clause :-
----------------

=> used to get specific row/rows from table based on a condition


=> where clause is associated with condition

Syntax :-

SELECT columns/*
FROM tabname
WHERE condition ;
condition :-
------------

COLNAME OP VALUE

=> OP must be any relational operator like > >= < <= = <>
=> if cond = true row is selected
=> if cond = false row is not selected

Examples :-

=> display employee details whose id = 103 ?

SELECT * FROM EMP WHERE EMPID = 103 ;

=> dislay employee details whose name is ravi ?

SELECT * FROM EMP WHERE ENAME = 'RAVI' ;

SELECT * FROM EMP WHERE ENAME = 'ravi' ; => no rows

NOTE :- in oracle string comparision is case sensitive i.e.


uppercase and lowercase strings are not same.

=> display employee details earning more than 5000 ?

SELECT * FROM EMP WHERE SAL > 5000 ;

=> display employee joined after 2020 ?

SELECT * FROM EMP WHERE HIREDATE > 2020 ; => ERROR

SELECT * FROM EMP WHERE HIREDATE > '31-DEC-20' ;

=> employees joined before 2020 ?

SELECT * FROM EMP WHERE HIREDATE < '01-JAN-20' ;

=> employees not working for dept 30 ?

SELECT * FROM EMP WHERE DEPTNO <> 30 ;

WHERE DEPTNO != 30 ;

Compound condition :-
---------------------

=> multiple conditions combined with AND / OR operators is called


compound condition.

WHERE COND1 AND COND2 RESULT


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

WHERE COND1 OR COND2 RESULT


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

Examples :-

=> employees working as clerk,manager ?

SELECT * FROM EMP WHERE JOB='CLERK' OR JOB='MANAGER' ;

=> employees whose id = 100,103,105 ?

SELECT * FROM EMP WHERE EMPID=100 OR EMPID=103 OR EMPID=105 ;

=> employees working for 20th dept and earning more than 5000 ?

SELECT * FROM EMP WHERE DEPTNO=20 AND SAL>5000 ;

=> employees earning more than 5000 and less than 10000 ?

SELECT * FROM EMP WHERE SAL>5000 AND SAL<10000 ;

=> employees joined in 2020 ?

SELECT * FROM EMP WHERE HIREDATE >= '01-JAN-2020'


AND
HIREDATE <= '31-DEC-2020' ;

=> employees working for 30th dept and working as analyst and earning
more than 5000 ?

SELECT *
FROM EMP
WHERE DEPTNO = 30 AND JOB='ANALYST' AND SAL>5000 ;

=> employees working as clerk,manager and earning more than 5000 ?

SELECT *
FROM EMP
WHERE JOB='CLERK' OR JOB='MANAGER' AND SAL>5000 ;

above query returns clerks earning less than 5000


because sal>5000 is applied only to manager but not to clerk
because operator AND has got more priority than operator OR ,
to control this use ( ).

SELECT *
FROM EMP
WHERE (JOB='CLERK' OR JOB='MANAGER') AND SAL>5000 ;

=>

STUDENT
SNO SNAME S1 S2 S3
1 A 80 90 70
2 B 30 60 50

=> list of students who are passed ?


SELECT *
FROM STUDENT
WHERE S1>=35 AND S2>=35 AND S3>=35 ;

=> list of students who are failed ?

SELECT *
FROM STUDENT
WHERE S1<35 OR S2<35 OR S3<35 ;

CREATE TABLE STUDENT


(
SNO NUMBER(2),
SNAME VARCHAR2(10),
S1 NUMBER(3),
S2 NUMBER(3),
S3 NUMBER(3)
);

INSERT INTO STUDENT VALUES(1,'A',80,90,70);


INSERT INTO STUDENT VALUES(2,'B',30,60,50);

IN operator :-
--------------

=> use IN operator for list comparision


=> use IN operator for "=" comparision with multiple values

WHERE COLNAME = V1,V2,V3,-- => INVALID


WHERE COLNAME IN (V1,V2,V3,---) => VALID

Ex :-

=> employees whose id = 100,103,105 ?

SELECT * FROM EMP WHERE EMPID IN (100,103,105) ;

=> employees working as CLERK,MANAGER ?

SELECT * FROM EMP WHERE JOB IN ('CLERK','MANAGER') ;

=> employees not working for dept 10,20 ?

SELECT * FROM EMP WHERE DEPTNO NOT IN (10,20) ;

BETWEEN operator :-
--------------------

=> use BETWEEN operator for range comparision

WHERE COLNAME BETWEEN V1 AND V2 (COL >= V1 AND COL <= V2)

COL = V1
OR
COL = V2 ==========> COL IN (V1,V2,V3)
OR
COL = V3
COL >= V1
AND ==========> COL BETWEEN V1 AND V2
COL <= V2

=> employees earning between 5000 and 10000 ?

SELECT * FROM EMP WHERE SAL BETWEEN 5000 AND 10000;

=> employees not joined in 2020 ?

SELECT *
FROM EMP
WHERE HIREDATE NOT BETWEEN '01-JAN-20' AND '31-DEC-20' ;

29-jul-24

SELECT *
FROM EMP
WHERE SAL BETWEEN 10000 AND 5000 ;

A ERROR
B NO ROWS
C RETURNS ROWS
D NONE

ANS :- B

WHERE SAL BETWEEN 5000 AND 10000 (SAL>=5000 AND SAL<=10000)

WHERE SAL BETWEEN 10000 AND 5000 (SAL>=10000 AND SAL<=5000)

NOTE :- use between operator with lower and upper


but don't use with upper and lower

=> display employees working as clerk,manager and earning between


5000 and 10000 and not joined in 2020 and not working dept 10,20 ?

SELECT *
FROM EMP
WHERE JOB IN ('CLERK','MANAGER')
AND
SAL BETWEEN 5000 AND 10000
AND
HIREDATE NOT BETWEEN '01-JAN-20' AND '31-DEC-20'
AND
DEPTNO NOT IN (10,20) ;

=> list of samsung,redmi,realme mobiles phones price between 10000 and 20000 ?

PRODUCTS
PRODID PNAME PRICE CATEGORY BRAND

SELECT *
FROM PRODUCTS
WHERE BRAND IN ('SAMSUNG','REDMI','REALME')
AND
PRICE BETWEEN 10000 AND 20000
AND
CATEGORY='MOBILES' ;
LIKE operator :-
-----------------

=> use LIKE operator for pattern comparision

ex :- name starts with 's'


name ends with 'd'
name contains 'a'

WHERE COLNAME LIKE 'PATTERN'

=> pattern may contain alphabets,digits,special char and wildcard chars

wildcard chars :-
------------------

% => 0 or many chars

_ => exactly 1 char

examples :-

=> employees name starts with 'S' ?

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

=> name ends with 'D' ?

SELECT * FROM EMP WHERE ENAME LIKE '%D' ;

=> name contains 'H' ?

SELECT * FROM EMP WHERE ENAME LIKE '%H%' ;

=> where 'H' is 3rd char in their name ?

SELECT * FROM EMP WHERE ENAME LIKE '__H%' ;

=> where 'H' is 3rd char from last ?

SELECT * FROM EMP WHERE ENAME LIKE '%H__' ;

=> name contains 4 chars ?

SELECT * FROM EMP WHERE ENAME LIKE '____' ;

=> employees joined in OCT month ? DD-MON-YY

SELECT * FROM EMP WHERE HIREDATE LIKE '___OCT___' ;

=> employees joined in 2020 year ?

SELECT * FROM EMP WHERE HIREDATE LIKE '%20' ;

=>

CUST
CID CNAME
10 SACHIN_TENDULKAR
11 VIRAT%KOHLI
12 MAHENDRA_SINGH_DHONI

=> list of customers name contains "_" ?

SELECT * FROM CUST WHERE CNAME LIKE '%_%' ;

above query returns all customer recoreds because "_" is not treated as
search char and it is treated as wildcard char , to overcome this problem
use ESCAPE char.

SELECT * FROM CUST WHERE CNAME LIKE '%\_%' ESCAPE '\' ;

the char that immediately follows "\" is not treated as wildcard char
and it is treated search char.

=> name contains % ?

SELECT * FROM CUST WHERE CNAME LIKE '%\%%' ESCAPE '\' ;

=> name contains 2 "_" ?

SELECT * FROM CUST WHERE CNAME LIKE '%\_%\_%' ESCAPE '\' ;

30-jul-24 :-
-------------

PAGESIZE :-
------------

=> no of rows displayed per page


=> default pagesize is 14
=> column headings are repeated for every page i.e. for every 14 rows
=> to increase the pagesize

SQL>SET PAGESIZE 100

IS operator :-
---------------

=> used to compare with NULL / NOT NULL

WHERE COLNAME IS NULL


WHERE COLNAME IS NOT NULL

=> display employees not earning commission ?

SELECT EMPNO,ENAME,SAL,COMM
FROM EMP
WHERE COMM IS NULL ;

=> employees earning commission ?

SELECT EMPNO,ENAME,SAL,COMM
FROM EMP
WHERE COMM IS NOT NULL ;
SUMMARY :-

WHERE COLNAME IN (V1,V2,V3,---)


WHERE COLNAME BETWEEN V1 AND V2
WHERE COLNAME LIKE 'PATTERN'
WHERE COLNAME IS NULL

Question :-

SELECT *
FROM EMP
WHERE JOB IN ('CLERK','MAN%') ;

A ERROR
B RETURNS CLERK,MANAGER
C RETURNS ONLY CLERK
D NONE

ANS :- C

WHERE JOB='CLERK' OR JOB LIKE 'MAN%' ;

ANS :- B

USER_TABLES :-
---------------

=> It is a system table that stores information about tables created


by user.

list of tables ?

SELECT TABLE_NAME FROM USER_TABLES ;

list of tables name starts with 'S' ?

SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME LIKE 'S%' ;

ALL_USERS :-
------------

=> stores information about users

list of users created in db ?

SELECT USERNAME FROM ALL_USERS ;

list of users created in july 2024 ?

SELECT USERNAME
FROM ALL_USERS
WHERE CREATED BETWEEN '01-JUL-24' AND '31-JUL-24' ;

ALIAS :-
--------

=> alias means another name or alternative name


=> used to change column headings
COLNAME / EXPR [AS] ALIAS

Examples :-

=> display ENAME ANNUAL SAL ?

SELECT ENAME,SAL*12 AS ANNSAL FROM EMP ;

SELECT ENAME,SAL*12 AS "ANNUAL SAL" FROM EMP ;

=> display ENAME EXPERIENCE in years ?

SELECT ENAME, (SYSDATE-HIREDATE)/365 AS EXPERIENCE FROM EMP ;

SELECT ENAME, ROUND((SYSDATE-HIREDATE)/365) AS EXPERIENCE FROM EMP ;

=> display ENAME SAL HRA DA TAX TOTSAL ?

HRA = house rent allowance = 20% on sal


DA = dearness allowance = 30% on sal
TAX = 10% on sal
TOTSAL = SAL + HRA + DA - TAX

SELECT ENAME,SAL,
SAL*0.2 AS HRA,
SAL*0.3 AS DA,
SAL*0.1 AS TAX,
SAL+(SAL*0.2)+(SAL*0.3)-(SAL*0.1) AS TOTSAL
FROM EMP ;

31-jul-24

ORDER BY clause :-
-------------------

=> ORDER BY clause is used to sort table data based on one or more columns
either in ascending or in descending order.

syntax :-

SELECT columns
FROM tabname
[WHERE cond]
ORDER BY colname ASC / DESC , ----- ;

=> default sort order is ascending

Examples :-

=> arrange employee list name wise ascending ?

SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY ENAME ASC ;

=> arrange employee list sal wise desc ?

SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY SAL DESC ;

1 A 3000 2 B 6000
2 B 6000 ======> 4 D 5000
3 C 4000 3 C 4000
4 D 5000 1 A 3000

=> arrange employee list hiredate wise asc ?

SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY HIREDATE ASC ;

note :-

=> in sorting nulls treated high


=> in ascending order displayed last
=> in descending order displayed first
=> to control this use NULLS LAST/FIRST option

=> arrange employee list comm wise desc but display nulls last ?

SELECT EMPNO,ENAME,SAL,COMM
FROM EMP
ORDER BY COMM DESC NULLS LAST ;

=> arrange employee list comm wise asc but display nulls first ?

SELECT EMPNO,ENAME,SAL,COMM
FROM EMP
ORDER BY COMM DESC NULLS FIRST;

=> arrange employee list dept wise asc and with in dept sal wise desc ?

SELECT EMPNO,ENAME,SAL,DEPTNO
FROM EMP
ORDER BY DEPTNO ASC , SAL DESC ;

1 A 3000 20 5 E 6000 10
2 B 4000 10 2 B 4000 10
3 C 2000 30 ==========> 4 D 5000 20
4 D 5000 20 1 A 3000 20
5 E 6000 10 3 C 2000 30

=> arrange student list avg wise desc,m desc,p desc ?

STUDENT
SNO SNAME M P C
1 A 80 90 70
2 B 60 50 70
3 C 90 70 80
4 D 90 80 70

SELECT STUDENT.* , (M+P+C)/3 AS AVG


FROM STUDENT
ORDER BY (M+P+C)/3 DESC , M DESC,P DESC ;
4 D 90 80 70
3 C 90 70 80
1 A 80 90 70
2 B 60 50 70

DISTINCT :-
-----------

=> distinct clause eliminates duplicates from select stmt output

SELECT DISTINCT COL1


SELECT DISTINCT COL1,COL2
SELECT DISTINCT *

Examples :-

SQL>SELECT DISTINCT DEPTNO FROM EMP ;

10
20
30

SQL>SELECT DISTINCT JOB FROM EMP ;

CLERK
MANAGER
ANALYST
SALESMAN
PRESIDENT

01-AUG-24

FETCH clause :-
---------------

=> FETCH clause is used to display top n rows

syntax :-
---------

SELECT columns
FROM tabname
[WHERE cond]
[ORDER BY ---]
[OFFSET ] FETCH FIRST/NEXT <n> ROWS ONLY ;

=> display first 5 rows from emp ?

SELECT EMPNO,ENAME,SAL
FROM EMP
FETCH FIRST 5 ROWS ONLY ;

=> display 5th row ?

SELECT EMPNO,ENAME,SAL
FROM EMP
OFFSET 4 ROWS FETCH NEXT 1 ROW ONLY ;

=> display 5th record to 10th record ?


SELECT EMPNO,ENAME,SAL
FROM EMP
OFFSET 4 ROWS FETCH NEXT 6 ROWS ONLY ;

=> display top 5 highest paid employees ?

SELECT EMPNO,ENAME,SAL
FROM EMP
ORDER BY SAL DESC
FETCH FIRST 5 ROWS ONLY ;

=> display top 3 max salaries ?

SELECT DISTINCT SAL


FROM EMP
ORDER BY SAL DESC
FETCH FIRST 3 ROWS ONLY ;

SAL
----------
5000
3000
2975

=> display 5th max salary ?

SELECT DISTINCT SAL


FROM EMP
ORDER BY SAL DESC
OFFSET 4 ROWS FETCH NEXT 1 ROW ONLY ;

=> display top 3 employees based on experience ?

SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY HIREDATE ASC
FETCH FIRST 3 ROWS ONLY ;

SUMMARY :-

WHERE => to select specific rows


ORDER BY => to sort table data
DISTINCT => to eliminate duplicates
FETCH => to display top n rows

DML commands :- (Data Manipulation Lang)


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

INSERT
UPDATE
DELETE
INSERT ALL
MERGE

TABLE = STRUCTURE (COLS) + DATA (ROWS)

DDL DML
=> all DML commands acts on table data.
=> all DML commands acts on instance which is temporary memory.
=> to save the operation execute commit.
=> to cancel the operation execute rollback.

UPDATE command :-
-------------------

=> command used to modify table data.


=> we can update all rows or specific rows.
=> we can update single column or multiple columns.

Syntax :-

UPDATE <tabname>
SET colname = value , colname = value , -------
[WHERE cond] ;

examples :-

=> update all employees comm with 500 ?

UPDATE EMP SET COMM = 500 ;

=> update employees comm with 500 whose comm = null ?

UPDATE EMP SET COMM = 500 WHERE COMM IS NULL ;

=> update comm with null whose comm <> null ?

UPDATE EMP SET COMM = NULL WHERE COMM IS NOT NULL ;

NULL assignment =
NULL comparision IS

=> update sal with 2000 and comm with 500 whose empno = 7369 ?

UPDATE EMP
SET SAL = 2000 , COMM = 500
WHERE EMPNO = 7369 ;

=> increment sal by 20% and comm by 10% those having more than 40 years of expr ?

UPDATE EMP
SET SAL = SAL + (SAL*0.2) , COMM = COMM + (COMM*0.1)
WHERE (SYSDATE-HIREDATE)/365 > 40 ;

=> transfer employees from 10th dept to 20th dept ?

UPDATE EMP SET DEPTNO = 20 WHERE DEPTNO = 10 ;

DELETE command :-
------------------

=> command used to delete row/rows from table.


=> we can delete all rows or specific rows.

syntax :- DELETE FROM <tabname> [WHERE cond] ;


=> delete all rows from emp table ?

DELETE FROM EMP ;

=> delete employees whose empno = 7369,7566,7844 ?

DELETE FROM EMP WHERE EMPNO IN (7369,7566,7844);

=> delete employees joined in 1983 year ?

DELETE FROM EMP WHERE HIREDATE BETWEEN '01-JAN-1983' AND '31-DEC-1983' ;

WHERE HIREDATE LIKE '%83' ;

DELETE FROM EMP WHERE SAL = 2000;

DDL commands :- (DATA DEFINITION LANG)


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

CREATE
ALTER
DROP
TRUNCATE
RENAME
FLASHBACK
PURGE

=> all DDL commands acts on table structure


=> all DDL commands are auto committed

DDL command = DDL command + commit

Example 1 :-

CREATE TABLE A(A NUMBER(2)); => COMMIT


INSERT INTO A VALUES(10);
INSERT INTO A VALUES(20);
ROLLBACK ;

SELECT * FROM A; => NO ROWS

Example 2 :-

CREATE TABLE A(A NUMBER(2)); => COMMIT


INSERT INTO A VALUES(10);
INSERT INTO A VALUES(20);
CREATE TABLE B(B NUMBER(2)); => COMMIT
INSERT INTO A VALUES(30);
INSERT INTO A VALUES(40);
ROLLBACK ;

SELECT * FROM A ;

10
20

ALTER command :-
----------------

=> command used to modify table structure


=> using ALTER command we can

1 add columns
2 drop columns
3 rename column
4 modify column
changing datatype
changing size

Adding columns :-
-----------------

ALTER TABLE <tabname>


ADD (colname datatype(size) , -----------);

Ex :-

=> add column gender to emp table ?

ALTER TABLE EMP


ADD (GENDER CHAR(1));

after adding by default the new column is filled with nulls ,


to insert data into the new column use UPDATE command.

1 UPDATE EMP SET GENDER = 'M' WHERE EMPNO = 7369 ;

2 SQL>UPDATE EMP SET GENDER = &GENDER WHERE EMPNO = &EMPNO ;


enter gender = 'F'
enter empno = 7499

1 row updated

SQL> / (executes previous command)

Droping column :-
------------------

ALTER TABLE <tabname>


DROP (col1,col2,-----) ;

Ex :-

=> drop column gender from emp ?

ALTER TABLE EMP


DROP (GENDER);

Renaming a column :-
---------------------

ALTER TABLE <tabname>


RENAME COLUMN <oldname> TO <newname> ;

Ex :-
=> rename column comm to bonus ?

ALTER TABLE EMP


RENAME COLUMN COMM TO BONUS ;

Modifying a column :-
---------------------

ALTER TABLE <tabname>


MODIFY (colname datatype(size));

=> increase size of ename to 20 ?

ALTER TABLE EMP


MODIFY (ENAME VARCHAR2(20))

ALTER TABLE EMP


MODIFY (ENAME VARCHAR2(5)); => ERROR => some names contains more than
5 chars.

=> increase the size of sal to 8,2 ?

ALTER TABLE EMP


MODIFY (SAL NUMBER(8,2));

ALTER TABLE EMP


MODIFY (SAL NUMBER(6,2)); => ERROR

NOTE :-

=> numeric field must be empty to decrease precision or scale.


=> column must be empty to change datatype

03-aug-24

How to change datatype of a column even if it contains data ?

STEP 1 :- add a new column

ALTER TABLE EMP


ADD (EMPID VARCHAR2(10));

STEP 2 :- copy data from empno to empid

UPDATE EMP SET EMPID = 'TCS'||EMPNO ;

STEP 3 :- remove the column empno

ALTER TABLE EMP DROP (EMPNO) ;

STEP 4 :- rename column empid to empno

ALTER TABLE EMP RENAME COLUMN EMPID TO EMPNO ;

DROP command :-
----------------

=> command used to drop table from db.


=> drops table structure along with data.
syn :- DROP TABLE <tabname> ;

Ex :-

SQL>DROP TABLE EMP ;

=> before 10g ver when table is dropped then it is permanently removed from db
and cannot be restored but from 10g onwards when table is dropped then
it is moved to recyclebin.

=> to see the recyclebin

SQL>SHOW RECYCLEBIN

FLASHBACK command :-
--------------------

=> command used to restore table from recyclebin.

syn :- FLASHBACK TABLE <tabname> TO BEFORE DROP ;

Ex :-

SQL>FLASHBACK TABLE EMP TO BEFORE DROP ;

=> table is restored with columns and rows that exists before drop

PURGE command :-
-----------------

=> command used to delete the table from recyclebin.


=> once table is purged we cannot flashback the table.

syntax :- PURGE TABLE <tabname> ;

Ex :-

SQL> PURGE TABLE EMP ;

DROP & PURGE :-


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

SQL>DROP TABLE CUST PURGE ; => table is dropped and also deleted from
recyclebin

TRUNCATE command :-
--------------------

=> deletes all the data from table but keeps structure.
=> will empty the table.
=> releases memory allocated for table.

SYN :- TRUNCATE TABLE <tabname> ;

EX :-

SQL>TRUNCATE TABLE EMP ;


=> when truncate command is executed oracle goes to memory and releases
all the blocks allocated for table and when blocks are relased
then data stored in blocks are also deleted.

DELETE VS TRUNCATE :-
--------------------

DELETE TRUNCATE

1 DML DDL

2 we can delete we can delete only


all rows and all rows but cannot
specific rows delete specific rows

3 where cond can where cond cannot be


be used with used with truncate
delete

4 delete operation truncate cannot be rolledback


can be rolledback

5 deletes row-by-row deletes all rows at a time

6 slower faster

7 will not release memory releases memory

5-aug-24

RENAME command :-
-----------------

=> command used to change tablename

RENAME <oldname> TO <newname> ;

Ex :-

=> rename table emp to employees ?

SQL>RENAME EMP TO EMPLOYEES ;

=> difference between alias and rename ?

SQL>SELECT ENAME,SAL,COMM AS BONUS FROM EMP ;

SQL>ALTER TABLE EMP RENAME COLUMN COMM TO BONUS ;

ALIAS RENAME

1 temporary permanent

2 changes column changes column name in table


heading in select
stmt output
===================================================================================

Built-in Functions in ORACLE :-


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

=> a function accepts some input performs some calculation and returns
one value

Types of functions :-
---------------------

1 CHARACTER
2 NUMERIC
3 DATE
4 CONVERSION
5 SPECIAL
6 ANALYTICAL / OLAP / WINDOW
7 GROUP / AGGREGATE

CHARACTER functions :-
---------------------

UPPER() :-
----------

=> converts string to uppercase

UPPER(arg)
string => 'hello'
column => ename

ex :-

SQL> SELECT UPPER('hello') FROM DUAL ; => HELLO

what is DUAL ?

DUAL is a dummy table provided by oracle used to select non db values.

LOWER() :-
-----------

=> converts string to lowercase

LOWER(arg)

Ex :-

SQL>SELECT LOWER('WELCOME') FROM DUAL ; => welcome

=> display EMPNO ENAME SAL ? display names in lowercase ?

SELECT EMPNO , LOWER(ENAME) AS ENAME ,SAL FROM EMP ;

=> convert names to lowercase in table ?

UPDATE EMP SET ENAME = LOWER(ENAME) ;


=> display employee details whose name is blake ?

SELECT *
FROM EMP
WHERE ENAME='BLAKE' ; => no rows

note :- in oracle string comparision is case sensitive , to perform


case insensitive use UPPER/LOWER functions.

SELECT *
FROM EMP
WHERE UPPER(ENAME) = 'BLAKE' ;

WHERE LOWER(ENAME) = 'blake' ;

INITCAP() :-
-------------

=> converts initials into capitals

INITCAP(arg)

Ex :-

SQL>SELECT INITCAP('sachin tendulkar') FROM DUAL ;

o/p :- Sachin Tendulkar

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

=> returns string length i.e. no of chars.

LENGTH(arg)

Ex :-

SQL>SELECT LENGTH('HELLO WELCOME') FROM DUAL ; => 13

=> display ENAME LENGTH ?

SELECT ENAME,LENGTH(ENAME) AS LEN FROM EMP ;

=> display employees where name contains 4 chars ?

SELECT * FROM EMP WHERE ENAME LIKE '____' ;

SELECT * FROM EMP WHERE LENGTH(ENAME) = 4 ;

SUBSTR() :-
-----------

=> returns part of the string based on start and length

SUBSTR(string,start,[length])

ex :-
SUBSTR('HELLO WELCOME',1,5) => HELLO
SUBSTR('HELLO WELCOME',10,3) => COM
SUBSTR('HELLO WELCOME',7) => WELCOME

SUBSTR('HELLO WELCOME',-5,4) => LCOM


SUBSTR('HELLO WELCOME',-7) => WELCOME

=> display employees name starts with 's' ?

WHERE ENAME LIKE 's%' ;

SELECT * FROM EMP WHERE SUBSTR(ENAME,1,1) = 's' ;

=> employees name ends with 's' ?

SELECT * FROM EMP WHERE SUBSTR(ENAME,-1,1) = 's' ;

=> employees name starts and ends with same char ?

WHERE ENAME LIKE 'a%a'


OR
ENAME LIKE 'b%b'
OR

SELECT * FROM EMP WHERE SUBSTR(ENAME,1,1) = SUBSTR(ENAME,-1,1) ;

=> generate emailids as follows ?

EMPNO ENAME EMAILID


7369 smith smi736@tcs.com
7499 allen all749@tcs.com

SELECT EMPNO,ENAME,
SUBSTR(ENAME,1,3)||SUBSTR(EMPNO,1,3)||'@tcs.com' AS EMAILID
FROM EMP ;

=> store emailids in db ?

step 1 :- add emailid column to emp table

ALTER TABLE EMP ADD (EMAILID VARCHAR2(20));

step 2 :- update the column with emailids

UPDATE EMP SET EMAILID = SUBSTR(ENAME,1,3)||SUBSTR(EMPNO,1,3)||'@tcs.com' ;

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

=> returns position of a char in a string.

INSTR(string,char,[start,occurance])

ex :-

INSTR('HELLO WELCOME','O') => 5


INSTR('HELLO WELCOME','K') => 0
INSTR('HELLO WELCOME','O',1,2) => 11
INSTR('HELLO WELCOME','L',1,3) => 9
INSTR('HELLO WELCOME','E',7,2) => 13

H E L L O W E L C O M E
1 2 3 4 5 6 7 8 9 10 11 12 13

INSTR('HELLO WELCOME','L',-1,3) => 3


INSTR('HELLO WELCOME','E',-5,2) => 2

=>

CUST
CID CNAME
10 SACHIN TENDULKAR
11 ROHIT SHARMA

display CID FNAME LNAME ?

FNAME = SUBSTR(CNAME,1,INSTR(CNAME,' ')-1)


LNAME = SUBSTR(CNAME,INSTR(CNAME,' ') + 1)

SELECT CID,
SUBSTR(CNAME,1,INSTR(CNAME,' ')-1) AS FNAME,
SUBSTR(CNAME,INSTR(CNAME,' ')+1) AS LNAME
FROM CUST ;

Assignment :-

CUST
CID CNAME
10 SACHIN RAMESH TENDULKAR
11 MAHENDRA SINGH DHONI

display FNAME MNAME LNAME ?

RPAD & LPAD :-


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

=> both functions are used to fill string with a character

RPAD(STRING,LEN,CHAR) => fills on right side


LPAD(STRING,LEN,CHAR) => fills on left side

ex :-

RPAD('HELLO',10,'*') => HELLO*****


LPAD('HELLO',10,'*') => *****HELLO
RPAD('*',10,'*') => **********

=>

ACCOUNTS
ACCNO BAL
12345678963 10000

your a/c no XXXX8963 debited --- ?

LPAD('X',4,'X')||SUBSTR(ACCNO,-4,4)
=> display ENAME SAL ?
***
****
*****

SELECT ENAME,RPAD('*',LENGTH(SAL),'*') AS SAL FROM EMP ;

07-AUG-24

LTRIM,RTRIM,TRIM :-
-------------------

=> used to remove spaces and unwanted chars.

LTRIM(string,[char]) => removes left side


RTRIM(string,[char]) => removes right side
TRIM(string) => removes both sides

ex :-

LTRIM(' HELLO ') => 'HELLO '


RTRIM(' HELLO ') => ' HELLO'
TRIM(' HELLO ') => 'HELLO'

LTRIM('@@@HELLO@@@','@') => HELLO@@@


RTRIM('@@@HELLO@@@','@') => @@@HELLO
TRIM(BOTH '@' FROM '@@@HELLO@@@') => HELLO

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

=> used to replace one string with another string

REPLACE(str1,str2,str3)

=> in str1 , str2 replaced with str3

ex :-

REPLACE('HELLO','ELL','ABC') => HABCO


REPLACE('HELLO','L','ABC') => HEABCABCO
REPLACE('HELLO','ELO','ABC') => HELLO
REPLACE('@@HE@@LL@@O@@','@','') => HELLO

=> employees list name contains 2 'A's ?

SELECT *
FROM EMP
WHERE LENGTH(ENAME) - LENGTH(REPLACE(ENAME,'a','')) = 2 ;
5 3

ex :- adams

=>

SQL> CREATE TABLE STUDENT(SNAME CHAR(10));


SQL> INSERT INTO STUDENT VALUES('james');

display student names ends with 's' ?

SQL> SELECT * FROM STUDENT WHERE SNAME LIKE '%s' ;

above query returns no rows because name is ended with space

ENAME CHAR(10)

j a m e s - - - - -

SQL>SELECT * FROM STUDENT WHERE RTRIM(SNAME) LIKE '%s' ;

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

=> used to translate one char to another char.

TRANSLATE(str1,str2,str3)

ex :-

TRANSLATE('HELLO','ELO','ABC') => HABBC

E => A
L => B
O => C

=> translate function can be used to encrypt data i.e. converting


plain text to cipher text.

DISPLAY ENAME SAL ? encrypt salaries ?

SELECT ENAME,
TRANSLATE(SAL,'0123456789','$bT*k@G^#%') AS SAL
FROM EMP ;

JONES 2975 T%^@

=> remove all special chars from '@#HE$%LL^*O!$' ?

o/p :- HELLO

SELECT
REPLACE(TRANSLATE('@#HE$%LL^*O!$','@#$%^*!','*******'),'*','') FROM DUAL;
---------------------------------------------
**HE**LL**O**

summary :-
-----------

UPPER,LOWER,INITCAP,LENGTH,SUBSTR,INSTR,RPAD,LPAD,RTRIM,LTRIM,TRIM,
REPLACE,TRANSLATE

8-aug-24

NUMERIC FUNCTIONS :-
--------------------
ABS() :-
---------

=> returns absolute value

ABS(number)

Ex :-

ABS(-10) => 10
ABS(10) => 10

POWER() :-
----------

=> calculates power

POWER(num1,num2)

Ex :-

POWER(3,2) => 9

SQRT() :-
---------

=> calculates square root

SQRT(number)

Ex :-

SQRT(16) => 4

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

=> returns whether given expr is positive or negative

SIGN(10) => 1
SIGN(-10) => -1
SIGN(10-10) => 0

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

=> returns remainder

MOD(num1,num2)

Ex :-

MOD(10,2) => 0

=> employees earning multiple of 100 ?

SELECT * FROM EMP WHERE MOD(SAL,100)=0 ;


ROUNDING NUMBERS :-
------------------

ROUND
TRUNC
CEIL
FLOOR

ROUND :-
--------

=> used to round number to integer or to decimal places.


=> round function acts according to avg.

ROUND(number,[decimal places])

ex :-

ROUND(38.5648) => 39

38---------------------38.5-----------------------39

number >= avg => rounded to highest


number < avg => rounded to lowest

ROUND(38.4567) => 38

ROUND(38.4567,2) => 38.46

ROUND(38.4537,2) => 38.45

ROUND(38.4567,3) => 38.457

ROUND(386,-2) => 400

300-------------------350----------------------400

ROUND(386,-1) => 390

380-------------------385-----------------------390

ROUND(386,-3) => 0

0----------------------500-------------------------1000

=>

SELECT ROUND(4567,-1) ,ROUND(4567,-2) , ROUND(4567,-3) FROM DUAL ;

O/P :- 4570 4600 5000

=> round all the employee salaries to hundreds in table ?

UPDATE EMP SET SAL = ROUND(SAL,-2) ;

=> display ENAME EXPERIENCE in years ?


SELECT ENAME, ROUND((SYSDATE-HIREDATE)/365) AS EXPR FROM EMP ;

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

=> rounds number always to lowest

TRUNC(number,[decimal places])

ex :-

TRUNC(38.9) => 38
TRUNC(38.5678,2) => 38.56
TRUNC(386,-2) => 300
TRUNC(999,-3) => 0

CEIL() :-
---------

=> rounds number always to highest

CEIL(number)

ex :-

CEIL(3.1) => 4

FLOOR() :-
----------

=> rounds number always to lowest

FLOOR(number)

Ex :-

FLOOR(3.9) => 3

DATE functions :-
-----------------

SYSDATE + 10 => 10 days added to sysdate


SYSDATE - 10 => 10 days subtracted from sysdate
SYSDATE - HIREDATE => calculates difference in days
SYSDATE + HIREDATE => invalid

rounding dates :-
------------------

=> ROUND & TRUNC functions can also be applied on dates.


=> dates can be rounded to year/month/day

ROUND(DATE , 'year/month/day')
TRUNC(DATE,'year/month/day')

Ex :- (SYSDATE = 08-AUG-24)
ROUND(SYSDATE,'YEAR') => 01-JAN-25

01-JAN-24--------------------30-JUN---------------------------01-JAN-25

ROUND(SYSDATE,'MONTH') => 01-AUG-24

01-AUG-24--------------------15-AUG---------------------------01-SEP-24

ROUND(SYSDATE,'DAY') => 11-AUG-24

04-AUG-24-----------------------THU------------------------------11-AUG-24

ROUND(SYSDATE) => 09-AUG-24

08-AUG-24-----------------------12:00PM--------------------------09-AUG-24

TRUNC(SYSDATE,'YEAR') => 01-JAN-24


TRUNC(SYSDATE,'MONTH') => 01-AUG-24
TRUNC(SYSDATE,'DAY') => 04-AUG-24
TRUNC(SYSDATE) => 08-AUG-24 00:00:00

09-aug-24

SCENARIO :-
-----------

INSERT INTO EMP(EMPNO,ENAME,SAL,HIREDATE) VALUES(100,'KKK',4000,SYSDATE);

=> list of employees joined today ?

SELECT * FROM EMP WHERE HIREDATE = SYSDATE ;

09-AUG-24 4:30:00 = 09-AUG-24 4:35:00

NOTE :- "=" comparision with SYSDATE always fails because oracle not
only compares date , it also compares time , to overcome this problem
apply TRUNC function on both sides.

SELECT * FROM EMP WHERE TRUNC(HIREDATE) = TRUNC(SYSDATE) ;

9-AUG-24 00:00:00 = 9-AUG-24 00:00:00

ADD_MONTHS() :-
----------------

=> used to add / subtract months to/from a date

ADD_MONTHS(DATE,NUMBER)

Ex :-

ADD_MONTHS(SYSDATE,2) => 09-OCT-24


ADD_MONTHS(SYSDATE,-2) => 09-JUN-24

scenario :-
GOLD_RATES
DATEID RATE
01-JAN-20 ?
02-JAN-20 ?

09-JUN-24 ?

display today's gold rate ?

SELECT * FROM GOLD_RATES WHERE TRUNC(DATEID) = TRUNC(SYSDATE) ;

display yesterday's gold rate ?

SELECT * FROM GOLD_RATES WHERE TRUNC(DATEID) = TRUNC(SYSDATE-1) ;

display last month same day gold rate ?

SELECT * FROM GOLD_RATES WHERE TRUNC(DATEID) = TRUNC(ADD_MONTHS(SYSDATE,-1));

display last year same day gold rate ?

SELECT * FROM GOLD_RATES WHERE TRUNC(DATEID) = TRUNC(ADD_MONTHS(SYSDATE,-12));

display last 1 month gold rates ?

SELECT *
FROM GOLD_RATES
WHERE TRUNC(DATEID) BETWEEN TRUNC(ADD_MONTHS(SYSDATE,-1)) AND TRUNC(SYSDATE) ;

WHERE TRUNC(DATEID) >= TRUNC(ADD_MONTHS(SYSDATE,-1)) ;

=> display list of employees joined in last 5 years ?

SELECT *
FROM EMP
WHERE TRUNC(HIREDATE) > TRUNC(ADD_MONTHS(SYSDATE,-60));

MONTHS_BETWEEN() :-
-----------------

=> returns no of months between two dates.

MONTHS_BETWEEN(DATE1,DATE2)

Ex :-

MONTHS_BETWEEN(SYSDATE,'09-AUG-23') => 12

=> display ENAME EXPERIENCE in months ?

SELECT ENAME,ROUND(MONTHS_BETWEEN(SYSDATE,HIREDATE)) AS EXPR FROM EMP ;

=> display ENAME EXPERIENCE ?


M YEARS N MONTHS

EXPERIENCE = 40 MONTHS = 3 YEARS 4 MONTHS

YEARS = MONTHS/12 = FLOOR(40/12) = 3


MONTHS = MOD(MONTHS,12) = MOD(40,12) = 4
SELECT ENAME,
FLOOR(MONTHS_BETWEEN(SYSDATE,HIREDATE)/12) AS YEARS ,
MOD(FLOOR(MONTHS_BETWEEN(SYSDATE,HIREDATE)),12) AS MONTHS
FROM EMP ;

LAST_DAY() :-
-------------

=> returns last day of the month

LAST_DAY(DATE)

Ex :-

LAST_DAY(SYSDATE) => 31-AUG-24

NEXT_DAY() :-
-------------

=> returns next given day starting from given date

NEXT_DAY(DATE,DAY)

Ex :-

NEXT_DAY(SYSDATE,'SUNDAY') => 11-AUG-24

Questions :-

1 display first day of the current year ?


2 display first day of the next year ?
3 display first day of the current month ?
3 display first day of the next month ?
4 display first sunday of the next month ?
5 display last sunday of the current month ?

CONVERSION :-
-------------

=> conversion means converting from one datatype to another datatype.


=> conversion is 2 types

1 implicit conversion
2 explicit conversion

Implicit conversion :-
----------------------

=> if conversion performed by oracle then it is called implicit conversion

Ex 1 :-

SQL>SELECT 5000 + '1000' FROM DUAL ; => 6000

string '1000' converted to number by oracle

Ex 2 :-
SQL>CREATE TABLE D(F1 DATE);

SQL>INSERT INTO D VALUES('09-AUG-24');

string '09-AUG-24' converted to date by oracle

10-aug-24

Explicit conversion :-
-----------------------

=> conversion performed by user is called explicit conversion


=> following functions provided by oracle for explicit conversion

1 TO_CHAR
2 TO_DATE
3 TO_NUMBER

converting date to char type :-


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

=> dates converted to char type to display dates in different formats

TO_CHAR(DATE , 'FORMAT') DATE = SYSDATE

FORMATS :-
-----------

YYYY => 2024


YY => 24
YEAR => TWENTY TWENTY FOUR

MM => 08
MON => AUG
MONTH => AUGUST

DDD => 223 (day of the year / 365)


DD => 10 (day of the month / 31)
D => 7 (day of the week / 7)
DY => SAT
DAY => SATURDAY

HH => hour part in 12 hrs format


HH24 => hour part in 24 hrs format
MI => minutes
SS => seconds
AM/PM => AM time or PM time

Q => Quarter (1-4)

JAN-MAR 1
APR-JUN 2
JUL-AUG 3
OCT-DEC 4

fm => format mask => removes extra spaces


Examples :-

=> Display ENAME YEAR_OF_JOIN MONTH ?

SELECT ENAME,
TO_CHAR(HIREDATE,'YYYY') AS YEAR_OF_JOIN ,
TO_CHAR(HIREDATE,'MONTH') AS MONTH
FROM EMP ;

=> Display ENAME DAY_OF_JOIN ?

SELECT ENAME,TO_CHAR(HIREDATE,'DAY') AS DAY FROM EMP ;

=> display employees joined on sunday ?

SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'D') = 1 ;

WHERE TO_CHAR(HIREDATE,'DY') = 'SUN' ;

WHERE TO_CHAR(HIREDATE,'fmDAY') = 'SUNDAY' ;

=> display employees joined in 1980,1983,1985 ?

SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'YYYY') IN (1980,1983,1985) ;

=> display employees joined in leap year ?

SELECT *
FROM EMP
WHERE MOD(TO_CHAR(HIREDATE,'YYYY'),4) = 0 ;

=> display employees joined in jan,apr,dec months ?

SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'MM') IN (1,4,12) ;

=> display employees joined in 2nd quarter of 1981 year ?

SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'YYYY') = 1981
AND
TO_CHAR(HIREDATE,'Q') = 2 ;

WHERE TO_CHAR(HIREDATE,'YYYY-Q') = '1981-2' ;

NOTE :-

=> by default oracle displays date but to display date & time use TO_CHAR

SELECT TO_CHAR(SYSDATE,'MM/DD/YYYY HH:MI:SS AM DAY') FROM DUAL ;

=>
SELECT ENAME,
TO_CHAR(HIREDATE,'YYYY-MM-DD HH:MI:SS AM') AS HIREDATE
FROM EMP ;

Converting number to char type :-


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

=> numbers are converted to char type to display numbers in different formats

TO_CHAR(NUMBER,'FORMAT')

FORMATS :-
----------

9 => represents a digit


0 => represents a digit
G => thousand seperator
D => decimal seperator
L => currency symbol
C => currency

Ex :-

TO_CHAR(5000,'99999') => 5000


TO_CHAR(5000,'00000') => 05000
TO_CHAR(500,'00000') => 00500
TO_CHAR(500,'99999') => 500
TO_CHAR(5000,'9G999') => 5,000
TO_CHAR(5000,'9G999D99') => 5,000.00
TO_CHAR(5000,'L9G999') => $5,000
TO_CHAR(5000,'C9G999') => USD5,000

=> display ENAME SAL ?


display salaries with thousand seperator and with currency symbol ?

SELECT ENAME,
TO_CHAR(SAL,'L9G999') AS SAL
FROM EMP ;

SMITH $800
ALLEN $1,600

How to change currency ?

SQL>ALTER SESSIION SET NLS_TERRITORY='INDIA' ;

SQL> SELECT ENAME,


TO_CHAR(SAL,'C9G999') AS SAL
FROM EMP ;

12-aug-24

converting char to date :-


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

TO_DATE(string,'format')
string => '12-aug-24'
'08/12/24'

Ex :-

SQL>SELECT SYSDATE + 10 FROM DUAL ; => 22-AUG-24

SQL>SELECT '01-OCT-24' + 200 FROM DUAL ; => ERROR

number + number valid


date + number valid
string + number invalid

SQL>SELECT TO_DATE('01-OCT-24','DD-MON-YY') + 200


FROM DUAL ;

O/P :- 19-APR-25

=> add 50 days to '08/15/2024' ?

SQL>SELECT TO_DATE('08/15/2024','MM/DD/YYYY') + 50 FROM DUAL ;

O/P := 04-OCT-24

=> write a query to display on which day india got independence ?

SELECT TO_CHAR(TO_DATE('15-AUG-1947','DD-MON-YYYY'),'DAY')
FROM DUAL ;

O/P :- FRIDAY

Converting string to number :-


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

string => '5000'


'5,000'
'$5,000'

TO_NUMBER(string,'format')

Ex :-

SQL>SELECT 5000 + '1,000' FROM DUAL ; => ERROR

SQL>SELECT 5000 + TO_NUMBER('1,000','9G999') FROM DUAL ; => 6000

=> calculate 'USD5,000' + '$1,000' ?

SQL> SELECT TO_NUMBER('USD5,000','C9G999') +


TO_NUMBER('$1,000','L9G999')
FROM DUAL ;

O/P :- 6000

INPUT OUTPUT FUNCTION

DD-MON-YY MM/DD/YY TO_CHAR


MM/DD/YY DD-MON-YY TO_DATE
DEFAULT OTHER TO_CHAR
OTHER DEFAULT TO_DATE

5000 $5,000 TO_CHAR


$5,000 5000 TO_NUMBER

Special :-
-----------

NVL() :-
---------

=> used to convert null values

NVL(arg1,arg2)

if arg1 = null returns arg2


if arg1 <> null returns arg1 only

Ex :-

NVL(100,200) => 100


NVL(NULL,200) => 200

=> display ENAME SAL COMM TOTSAL ?

TOTSAL = SAL + COMM

SELECT ENAME,SAL,COMM,SAL+COMM AS TOTSAL FROM EMP ;

SMITH 800 NULL NULL


ALLEN 1600 300 1900

SELECT ENAME,SAL,COMM,SAL+NVL(COMM,0) AS TOTSAL FROM EMP ;

SMITH 800 NULL 800


ALLEN 1600 300 1900

=> display ENAME SAL COMM ?

if comm = null display N/A ?

SELECT ENAME,SAL,NVL(COMM,'N/A') AS COMM FROM EMP ; => ERROR

SELECT ENAME,SAL,NVL(TO_CHAR(COMM),'N/A') AS COMM FROM EMP ;

NOTE :- in NVL function both arguments must be same type

ASCII() :-
-----------

=> returns ascii value

ASCII(char)

Ex :-

SQL>SELECT ASCII('A') FROM DUAL ; => 65


CHR() :-
----------

=> returns character for givne ascii value

CHR(ASCII VALUE)

Ex :-

SQL>SELECT CHR(65) FROM DUAL ;

How to implement loop in sql :-


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

SELECT LEVEL FOR(LEVEL=1;LEVEL<=10;LEVEL++)


FROM DUAL {
CONNECT BY LEVEL <= 10 ; PRINT LEVEL ;
}

=> level is a system variable


=> level initialized to 1
=> by default level is incremented by 1
=> this is continued till the condition CONNECT BY LEVEL<=10 false.

SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= 100 ;

=> write a query to print even numbers upto 20 ?

SELECT LEVEL
FROM DUAL
WHERE MOD(LEVEL,2) = 0
CONNECT BY LEVEL <= 20 ;

=> write a query to print all ascii chars ?

ascii char
1 ?
2 ?

65 A

97 a

SELECT LEVEL , CHR(LEVEL)


FROM DUAL
CONNECT BY LEVEL <= 256 ;

=> write a query to display 2024 calendar ?

DATE DAY
01-JAN-24 ?
02-JAN-24 ?

31-DEC-24 ?
SELECT LEVEL + TO_DATE('31-DEC-2023','DD-MON-YYYY') AS DATEID,
TO_CHAR(LEVEL + TO_DATE('31-DEC-2023','DD-MON-YYYY') ,'DAY') AS DAY
FROM DUAL
CONNECT BY LEVEL <= 366 ;

=> write a query to print following patttern ?

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

SELECT RPAD('*',LEVEL,'*')
FROM DUAL
CONNECT BY LEVEL < =10 ;

=> write a query to print following pattern ?

SELECT RPAD(' ',10-LEVEL,' ')||


RPAD('*',LEVEL,'*')||
RPAD('*',LEVEL-1,'*')
FROM DUAL
CONNECT BY LEVEL < =10 ;

*
***
*****

13-AUG-24

ANALYTICAL FUNCTIONS / OLAP / WINDOW :-


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

RANK & DENSE_RANK :-


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

=> both functions are used to find ranks.


=> ranking is always based on some field.
=> for rank functions data must be sorted

RANK() OVER (ORDER BY COLNAME ASC/DESC)


DENSE_RANK() OVER (ORDER BY COLNAME ASC/DESC)

Ex :-

=> find ranks of the employees based on sal and highest paid should get 1st
rank ?

SELECT EMPNO,ENAME,SAL,
RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ;

SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ;

difference between rank & dense_rank ?


1 rank functions generates gaps but dense_rank will not generate gaps.

2 in rank function ranks may not be in sequence but in dense_rank


ranks are always in sequence.

SAL RANK DENSE_RANK


5000 1 1
4000 2 2
3000 3 3
3000 3 3
3000 3 3
2000 6 4
2000 6 4
1000 8 5

=> find ranks based on sal if salaries are same then ranking should be
based on hiredate ?

SELECT EMPNO,ENAME,HIREDATE,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC,HIREDATE ASC) AS RNK
FROM EMP ;

14-AUG-24

PARTITION BY clause :-
------------------------

=> partition by clause is used to divide the table based on one or more columns.

=> partitioning is required to find ranks with in group , for ex to find


ranks with in dept first divide the table dept wise and apply rank/dense_rank
functions on each dept.

ex :-

SQL> BREAK ON DEPTNO SKIP 1

SQL>SELECT DEPTNO,ENAME,SAL,
DENSE_RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) AS RNK
FROM EMP ;

LAG() & LEAD() :-


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

LAG(COLNAME , NUM) OVER (ORDER BY -) => returns previous value


LEAD(COLNAME, NUM) OVER (ORDER BY --) => returns next value

Ex :-

SELECT EMPNO,ENAME,SAL,
LAG(SAL,1) OVER (ORDER BY EMPNO ASC) AS PREV_SAL
FROM EMP ;

7369 SMITH 800 NULL


7499 ALLEN 1600 800
7521 WARD 1250 1600
scenario :-

GOLD_RATES
YEAR RATE
2020 40000
2021 48000
2022 54000
2023 60000
2024 65000

SELECT YEAR,RATE,
RATE - LAG(RATE,1) OVER (ORDER BY YEAR ASC) AS CHANGE
FROM GOLD_RATES ;

YEAR RATE CHANGE


---------- ---------- ----------
2020 40000
2021 48000 8000
2022 54000 6000
2023 60000 6000
2024 65000 5000

=> display EMPNO ENAME HIREDATE DAYS ?

SELECT EMPNO,ENAME,HIREDATE,
HIREDATE - LAG(HIREDATE,1) OVER (ORDER BY HIREDATE ASC) AS DAYS
FROM EMP ;

7369 smith 17-DEC-80 NULL


7499 allen 20-FEB-81 65
7521 ward 22-FEB-81 2
7566 jones 02-APR-81 39

GROUP / AGGREGATE functions :-


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

=> GROUP functions process multiple rows and returns one value

MAX
MIN
SUM
AVG
COUNT
COUNT(*)

MAX() :-
---------

=> returns maximum value

MAX(arg)
COLNAME

Ex :-

SQL>SELECT MAX(SAL) FROM EMP ; => 5000


SQL>SELECT MAX(HIREDATE) FROM EMP ; => 12-JAN-83
SQL>SELECT MAX(ENAME) FROM EMP ; => ward
MIN() :-
--------

=> returns minimum value

MIN(colname)

Ex :-

SQL>SELECT MIN(SAL) FROM EMP ; => 800


SQL>SELECT MIN(HIREDATE) FROM EMP ; => 17-DEC-80
SQL>SELECT MIN(ENAME) FROM EMP ; => adams

SUM() :-
---------

=> returns total

SUM(colname)

Ex :-

SQL>SELECT SUM(SAL) FROM EMP ; => 29025

=> round total sal to hundreds ?

SQL>SELECT ROUND(SUM(SAL),-2) FROM EMP ; => 29000

29000------------29050--------------29100

=> after rounding display total sal with thousand seperator and currency symbol ?

SQL>SELECT TO_CHAR(ROUND(SUM(SAL),-2),'C99G999') FROM EMP ; => $29,000

16-AUG-24

=> calculate total sal including comm ?

SQL>SELECT SUM(SAL+COMM) FROM EMP ;

SAL COMM SAL+COMM


5000 NULL NULL
3000 500 3500
4000 NULL NULL

SUM(SAL) = 12000
SUM(SAL+COMM) = 3500

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

SAL COMM SAL+NVL(COMM,0)


5000 NULL 5000
3000 500 3500
4000 NULL 4000

SUM(SAL) = 12000
SUM(SAL+NVL(COMM,0)) = 12500
AVG() :-
----------

=> returns average value

AVG(colname)

Ex :-

SQL>SELECT AVG(SAL) FROM EMP ; => 2073.21429

=> round the average sal to integer ?

SQL>SELECT FLOOR(AVG(SAL)) FROM EMP ; => 2073

NOTE :- SUM,AVG functions cannot be applied on char,date columns

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

=> returns no of values present in a column

COUNT(colname)

Ex :-

SQL>SELECT COUNT(EMPNO) FROM EMP ; => 14

SQL>SELECT COUNT(COMM) FROM EMP ; => 4 => nulls are not counted

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

=> returns no of rows in a table

SQL>SELECT COUNT(*) FROM EMP ; => 14

T1
F1
10
NULL
20
NULL
30

COUNT(F1) => 3
COUNT(*) => 5

difference between COUNT & COUNT(*) ?

COUNT doesn't include nulls in counting


COUNT(*) includes nulls in counting

=> how many employees joined in 1981 year ?

SELECT COUNT(*)
FROM EMP
WHERE HIREDATE BETWEEN '01-JAN-1981' AND '31-DEC-1981' ;
WHERE HIREDATE LIKE '%81' ;

WHERE TO_CHAR(HIREDATE,'YYYY') = 1981 ;

=> find no of employees joined on sunday ?

SELECT COUNT(*)
FROM EMP
WHERE TO_CHAR(HIREDATE,'dy') = 'sun' ;

TO_CHAR(HIREDATE,'fmday') = 'sunday' ;

=> find no of employees joined in 2nd quarter of 1981 year ?

SELECT COUNT(*)
FROM EMP
WHERE TO_CHAR(HIREDATE,'YYYY') = 1981
AND
TO_CHAR(HIREDATE,'Q') = 2 ;

summary :-
----------

CHAR :- upper,lower,initicap,length,substr,instr,rpad,lpad,rtrim,ltrim,trim,
replace,translate

NUMERIC :- abs,power,sqrt,mod,round,trunc,ceil,floor

DATE :- add_months,months_between,last_day,next_day

CONVERSION :- to_char,to_date,to_number

SPECIAL :- nvl,ascii,chr

ANALYTICAL :- rank,dense_rank,lag,lead

GROUP :- max,min,sum,avg,count,count(*)

CASE statement :-
------------------

=> used to implement if-then-else.


=> case statement is similar to switch case.
=> using case statement we can return values based on conditions.
=> case statements are 2 types

1 simple case
2 searched case

simple case :-
--------------

=> use simple case when conditions based on "=" operator

CASE COLNAME / EXPR


WHEN VALUE1 THEN RETURN EXPR1
WHEN VALUE2 THEN RETURN EXPR2
-------------------
ELSE RETURN EXPR
END

Ex 1 :-

display ENAME JOB ?

IF JOB=CLERK DISPLAY WORKER


MANAGER BOSS
PRESIDENT BIG BOSS
OTHERS EMPLOYEE

SELECT ENAME,
CASE JOB
WHEN 'CLERK' THEN 'WORKER'
WHEN 'MANAGER' THEN 'BOSS'
WHEN 'PRESIDENT' THEN 'BIG BOSS'
ELSE 'EMPLOYEE'
END AS JOB
FROM EMP ;

=> increment employee salaries as follows ?

IF DEPTNO = 10 INCR SAL BY 10%


20 15%
30 20%
OTHERS 5%

UPDATE EMP
SET SAL = CASE DEPTNO
WHEN 10 THEN SAL+(SAL*0.1)
WHEN 20 THEN SAL + (SAL*0.15)
WHEN 30 THEN SAL + (SAL*0.2)
ELSE SAL + (SAL*0.05)
END ;

17-AUG-24

Searched case :-
-----------------

=> use searched case when conditions not based on "=" operator

CASE
WHEN COND1 THEN RETURN EXPR1
WHEN COND2 THEN RETURN EXPR2
-----------------
ELSE RETURN EXPR
END

=> display ENAME SAL SALRANGE ?

IF SAL>3000 DISPLAY HISAL


SAL<3000 LOSAL
SAL=3000 AVGSAL

SELECT ENAME,SAL,
CASE
WHEN SAL>3000 THEN 'HISAL'
WHEN SAL<3000 THEN 'LOSAL'
ELSE 'AVGSAL'
END AS SALRANGE
FROM EMP ;

=> display SNO TOTAL AVG RESULT ?

STUDENT
SNO SNAME S1 S2 S3
1 A 80 90 70
2 B 30 60 50

SELECT SNO,
S1+S2+S3 AS TOTAL,
ROUND((S1+S2+S3)/3,1) AS AVG,
CASE
WHEN S1>=35 AND S2>=35 AND S3>=35 THEN 'PASS'
ELSE 'FAIL'
END AS RESULT
FROM STUDENT ;

1 240 80 PASS
2 140 46.7 FAIL

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

INTEGRITY CONSTRAINTS
=====================

=> integrity constraints are rules to maintain data quality or data consistency
=> used to prevent users from entering invalid data
=> used to enforce rules like min bal must be 1000

Types of constraints :-
-----------------------

1 NOT NULL
2 UNIQUE
3 PRIMARY KEY
4 CHECK
5 FOREIGN KEY
6 DEFAULT

=> above constraints can be declared in two ways

1 column level
2 table level

column level :-
---------------

=> if constraints are declared immediately after declaring column


then it is called column level.

CREATE TABLE <tabname>


(
colname datatype(size) constraint ,
colname datatype(size) constraint,
----------------
) ;

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

=> NOT NULL constraint doesn't accept null values


=> a field declared with not null is called mandatory field

Ex :-

CREATE TABLE EMP11


(
EMPNO NUMBER(4),
ENAME VARCHAR2(10) NOT NULL
);

INSERT INTO EMP11 VALUES(100,''); => ERROR


INSERT INTO EMP11 VALUES(101,'A');

19-aug-24

UNIQUE :-
----------

=> a column declared with UNIQUE doesn't accept duplicates

ex :-

CREATE TABLE EMP12


(
EMPID NUMBER(4) ,
ENAME VARCHAR2(10) NOT NULL,
EMAILID VARCHAR2(20) UNIQUE
);

INSERT INTO EMP12 VALUES(100,'A','abc@gmail.com');


INSERT INTO EMP12 VALUES(101,'B','abc@gmail.com'); => ERROR
INSERT INTO EMP12 VALUES(102,'C',''); => ACCEPTED
INSERT INTO EMP12 VALUES(103,'D',''); => ACCEPTED

NOTE :- unique constraint allows nulls

PRIMARY KEY :-
--------------

=> primary key doesn't accept duplicates and nulls.


=> it is the combination of unique and not null.
=> In tables one column must be there to uniquely identify the records
and into that column duplicates and nulls are not allowed , so declare
that column with primary key.

Ex :-

CREATE TABLE EMP13


(
EMPID NUMBER(4) PRIMARY KEY,
ENAME VARCHAR(20) NOT NULL
);

INSERT INTO EMP13 VALUES(100,'A');


INSERT INTO EMP13 VALUES(100,'B'); => ERROR
INSERT INTO EMP13 VALUES(NULL,'C'); => ERROR

NOTE :- a table can have only one primary key , if we want multiple
primary keys then declare one column with primary key and other
columns with unique not null.

Ex :-

CREATE TABLE CUST


(
CUSTID NUMBER(4) PRIMARY KEY,
NAME VARCHAR2(10) NOT NULL,
AADHARNO NUMBER(12) UNIQUE NOT NULL,
PANNO CHAR(10) UNIQUE NOT NULL
);

=> difference between unique & primary key ?

unique primary key

1 allows nulls doesn't allow nulls

2 a table can have a table can have


multiple unique only one primary key

CHECK :-
---------

=> use check constraint when rule based on conditions

CHECK(condition)

Ex 1 :- sal must be min 5000

CREATE TABLE EMP14


(
EMPID NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10) NOT NULL,
SAL NUMBER(7,2) CHECK(SAL>=5000)
);

INSERT INTO EMP14 VALUES(100,'A',1000); => ERROR


INSERT INTO EMP14 VALUES(101,'B',5000); => ACCEPTED
INSERT INTO EMP14 VALUES(102,'C',NULL); => ACCEPTED

NOTE :- CHECK constraint allows null values

Ex 2 :- GENDER must be 'M','F' ?

GENDER CHAR(1) CHECK(GENDER IN ('M','F'))

Ex 3 :- AMT must be multiple of 100 ?

AMT NUMBER(6) CHECK(MOD(AMT,100)=0)


Ex 4 :- PWD must be min 6 chars

PWD VARCHA2(12) CHECK(LENGTH(PWD) >= 6)

Ex 5 :- EMAILID must contain '@'


EMAILID must end with '.com' or '.co' or '.in'

EMAILID VARCHAR2(20) CHECK(EMAILID LIKE '%@%'


AND
(
EMAILID LIKE '%.com'
OR
EMAILID LIKE '%.co'
OR
EMAILID LIKE '%.in'
))

20-aug-24

FOREIGN KEY :-
--------------

=> foreign key is used to establish relationship between two tables

=> To establish relationship between two tables , take primary key


of one table and add it to another table as foreign key and
declare with references constraint.

ex :-

PROJECTS
PROJID PNAME DURATION COST CLIENT
100 ABC 5 100 TATA
101 KLM 3 80 BANK

EMP
EMPID ENAME JOB SAL PROJID REFERENCES PROJECTS(PROJID)
1 A SE ? 100
2 B SSE ? 101
3 C SE ? 999 => INVALID
4 D SSE ? 100
5 E SE ? NULL

=> values entered in foreign key column should match with values entered in
primary key column.

=> foreign key allows duplicates and nulls

=> after declaring foreign key a relationship is established between two tables
called parent/child relationship.

=> PK table is parent and FK table is child.

CREATE TABLE PROJECTS


(
PROJID NUMBER(3) PRIMARY KEY ,
PNAME VARCHAR2(10) NOT NULL,
CLIENT VARCHAR2(15)
);

INSERT INTO PROJECTS VALUES(100,'ABC','TATA MOTORS');


INSERT INTO PROJECTS VALUES(101,'KLM','KLM AIRLINES');

CREATE TABLE EMP55


(
EMPID NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10) NOT NULL,
SAL NUMBER(7,2) CHECK(SAL>=3000),
PROJID NUMBER(3) REFERENCES PROJECTS(PROJID)
);

INSERT INTO EMP55 VALUES(1,'A',5000,100);


INSERT INTO EMP55 VALUES(2,'B',6000,999); => ERROR
INSERT INTO EMP55 VALUES(3,'C',4000,100);
INSERT INTO EMP55 VALUES(4,'D',3000,NULL);

DEFAULT :-
----------

=> a column can be declared with default value as follows

ex :- HIREDATE DATE DEFAULT SYSDATE

=> while inserting if we skip hiredate then oracle inserts default value.

CREATE TABLE EMP66


(
EMPNO NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10) NOT NULL,
HIREDATE DATE DEFAULT SYSDATE
);

INSERT INTO EMP66(EMPNO,ENAME) VALUES(100,'A');


INSERT INTO EMP66 VALUES(101,'B','01-JAN-24');
INSERT INTO EMP66 VALUES(102,'C','');

SELECT * FROM EMP66

1 A 20-AUG-24
2 B 01-JAN-24
3 C

Assignment :-

=> create following tables with given rules ?

ACCOUNTS
ACCNO ACTYPE BAL

Rules :-
--------

1 accno should not be duplicate & null


2 actype must be 'S' OR 'C'
3 bal must be min 1000

TRANSACTIONS
TRID TTYPE TDATE TAMT ACCNO

Rules :-
---------

1 trid should not be duplicate & null


2 ttype must be 'W' OR 'D'
3 tdate always sysdate
4 tamt must be multiple of 100
5 accno should present in accounts table

TABLE LEVEL :-
----------------

=> if constraint are declared after declaring all columns then it is called table
level
=> use table level to declare constraints for multiple or combination of columns

Declaring check constraint at table level :-


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

PRODUCTS
PRODID PNAME PRICE MFD_DT EXP_DT
10 A 50 01-AUG-24 01-JAN-24 INVALID

RULE :- EXP_DT > MFD_DT

CREATE TABLE PRODUCTS


(
PRODID NUMBER(3) PRIMARY KEY,
PNAME VARCHAR2(10),
MFD_DT DATE ,
EXP_DT DATE ,
CHECK(EXP_DT > MFD_DT)
);

INSERT INTO PRODUCTS VALUES(100,'A','01-AUG-24' , '01-JAN-24'); => ERROR

21-aug-24

composite primary key :-


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

=> if combination of columns declared primary key then it is called composite


primary key.

=> In some tables we may not able to uniquely identify the records using single
column
we need combination of columns to uniquely identify the records and that
combination
should be declared primary key at table level.

ex :-

STUDENT COURSE
SID SNAME CID CNAME
1 A 10 JAVA
2 B 11 ORACLE
REGISTRATIONS
SID CID DOR FEE
1 10 ? ?
1 11 ? ?
2 10 ? ?

=> in above table sid,cid combination uniquely identify the records, so declare
this
combination as primary key at table level.

CREATE TABLE REGISTRATIONS


(
SID NUMBER(2) ,
CID NUMBER(2) ,
DOR DATE,
FEE NUMBER(5) ,
PRIMARY KEY(SID,CID)
);

INSERT INTO REGISTRATIONS VALUES(1,10,SYSDATE,5000);


INSERT INTO REGISTRATIONS VALUES(1,11,SYSDATE,4000);
INSERT INTO REGISTRATIONS VALUES(2,10,SYSDATE,4000);
INSERT INTO REGISTRATIONS VALUES(1,10,SYSDATE,4000); => ERROR

Ex 2 :-

=> identify primary key and write create table script ?

SALES
DATEID PRODID CUSTID QTY AMT
20-AUG-24 100 10 1 2000
20-AUG-24 100 11 1 2000
20-AUG-24 101 10 1 1000
21-AUG-24 100 10 1 2000

composite foreign key :-


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

=> if combination of columns declared foreign key then it is called composite


foreign key.

=> composite foreign key refers composite primary key.

ex :-

REGISTRATIONS
SID CID DOR FEE
1 10 ? ?
1 11 ? ?
2 10 ? ?

CERTIFICATES
CERTNO DOI SID CID
1000 ?? 1 10
1001 ?? 1 11
1002 ?? 2 11 => INVALID

=> In the above example sid,cid combination should match with registrations table
sid,cid
combination , so declare this combination as foreign key at table level.

CREATE TABLE CERTIFICATES


(
CERTNO NUMBER(4) PRIMARY KEY,
DOI DATE,
SID NUMBER(2) ,
CID NUMBER(2) ,
FOREIGN KEY(SID,CID) REFERENCES REGISTRATIONS(SID,CID)
);

Which of the following constraint cannot be declared at table level ?

A UNIQUE
B CHECK
C NOT NULL
D FOREIGN KEY
E PRIMARY KEY

ANS :- C

Adding constraints to existing table :-


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

=> "ALTER" command is used to add constraints to existing table

CREATE TABLE EMP55


(
EMPID NUMBER(4),
ENAME VARCHAR2(10),
SAL NUMBER(7,2),
EMAILID VARCHAR2(10),
DNO NUMBER(2)
);

Adding primary key :-


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

=> add primary key to empid ?

ALTER TABLE EMP55


ADD PRIMARY KEY(EMPID);

NOTE :- primary key cannot be added to the column that already contains
duplicates & nulls

Adding check constraint :-


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

=> add check constraint with condition sal >= 3000 ?

ALTER TABLE EMP55


ADD CHECK(SAL>=3000);

ALTER TABLE EMP


ADD CHECK(SAL>=3000); => ERROR => some employee salaries are less than 3000
NOVALIDATE :-
--------------

=> if check constraint added with NOVALIDATE then oracle will not validate
existing data
and it validates only new data.

ALTER TABLE EMP


ADD CHECK(SAL>=3000) NOVALIDATE ;

Adding unique constraint :-


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

=> add unique to emailid ?

ALTER TABLE EMP55


ADD UNIQUE(EMAILID) ;

Adding foreign key :-


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

=> add fk to dno that refers dept table primary key i.e. deptno ?

ALTER TABLE EMP55


ADD FOREIGN KEY(DNO) REFERENCES DEPT(DEPTNO) ;

Changing from NULL TO NOT NULL :-


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

=> modify column ename to not null ?

ALTER TABLE EMP55


MODIFY(ENAME NOT NULL) ;

22-AUG-24

USER_CONSTRAINTS :
-------------------

=> system table that stores constraints declared in tables

=> list of constraints declared in emp55 table ?

SQL>COLUMN CONSTRAINT_NAME FORMAT A20


SQL>COLUMN SEARCH_CONDITION FORMAT A30

SQL>SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,
SEARCH_CONDITION
FROM USER_CONSTRAINTS
WHERE TABLE_NAME='EMP55' ;

CONSTRAINT_NAME C SEARCH_CONDITION
-------------------- - ------------------------------
SYS_C007566 R
SYS_C007562 C SAL>=3000
SYS_C007567 C "ENAME" IS NOT NULL
SYS_C007561 P
SYS_C007564 U
Droping constraints :-
----------------------

ALTER TABLE <TABNAME>


DROP CONSTRAINT <NAME> ;

Ex :-

=> drop check constraint in emp55 table ?

ALTER TABLE EMP55


DROP CONSTRAINT SYS_C007562 ;

=> drop primary key in emp55 table ?

ALTER TABLE EMP55


DROP PRIMARY KEY ;

=> drop primary key in dept table ?

ALTER TABLE DEPT


DROP PRIMARY KEY ; => ERROR

DROP TABLE DEPT ; => ERROR

NOTE :-

=> primary key constraint cannot be dropped if referenced by some fk


=> primary key table cannot be dropped if referenced by some fk

CASCADE option :-
-----------------

ALTER TABLE DEPT


DROP PRIMARY KEY CASCADE ; => drops primary key with dependenct
foreign key

DROP TABLE DEPT CASCADE CONSTRAINTS ; => drops table with dependent foreign key

DELETE RULES :-
---------------

ON DELETE NO ACTION (DEFAULT)


ON DELETE CASCADE
ON DELETE SET NULL

=> these rules are declared with foreign key


=> delete rule specifies how child rows are affected if parent row is deleted

ON DELETE NO ACTION :-
----------------------

=> parent row cannot be deleted if associated with child rows

create table dept99


(
dno number(2) primary key,
dname varchar2(10)
);

insert into dept99 values(10,'hr');


insert into dept99 values(20,'it');

create table emp99


(
empno number(4) primary key,
ename varchar2(10),
dno number(2) references dept99(dno)
);

insert into emp99 values(1,'A',10);


insert into emp99 values(2,'B',10);

DELETE FROM DEPT99 WHERE DNO = 10 ; => ERROR

scenario :-

ACCOUNTS
ACCNO ACTYPE
100 S
101 C

LOANS
ID TYPE AMT ACCNO
1 H 40 100
2 C 10 100

RULE :- account closing is not possible if associated with loans.

ON DELETE CASCADE :-
--------------------

=> if parent row is deleted then it is deleted along with child rows.

create table dept99


(
dno number(2) primary key,
dname varchar2(10)
);

insert into dept99 values(10,'hr');


insert into dept99 values(20,'it');

create table emp99


(
empno number(4) primary key,
ename varchar2(10),
dno number(2) references dept99(dno) ON DELETE CASCADE
);

insert into emp99 values(1,'A',10);


insert into emp99 values(2,'B',10);

DELETE FROM DEPT99 WHERE DNO = 10 ; => row deleted

SELECT * FROM EMP99 ; => no rows


ON DELETE SET NULL :-
----------------------

=> if parent row is deleted then it is deleted but child rows are not deleted but
fk
will be set to null.

create table dept99


(
dno number(2) primary key,
dname varchar2(10)
);

insert into dept99 values(10,'hr');


insert into dept99 values(20,'it');

create table emp99


(
empno number(4) primary key,
ename varchar2(10),
dno number(2) references dept99(dno) ON DELETE SET NULL
);

insert into emp99 values(1,'A',10);


insert into emp99 values(2,'B',10);

DELETE FROM DEPT99 WHERE DNO=10; => 1 ROW DELETED

SELECT * FROM EMP99 ;

1 A NULL
2 B NULL

Summary :-

importance of constraints
declaring constraints
column level
table level
adding constraints
removing constraints
delete rules
getting constraints information

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

JOINS
=====

=> join is an operation performed to display data from two or more tables.

=> In db related data stored in multiple tables , to gather or to combine


data stored in multiple table we need to join those tables.

ex :-

ORDERS CUSTOMERS
ORDID ORDDT DELDT CID CID CNAME ADDR
1000 23/ 25/ 10 10 A HYD
1001 23/ 26/ 11 11 B HYD

OUTPUT :-

ORDID ORDDT DELDT CNAME ADDR


1000 23/ 25/ A HYD
------------------- ------------
orders cust

Types of joins :-
----------------

1 INNER JOIN
EQUI JOIN
NON EQUI
SELF JOIN
2 OUTER JOIN
LEFT OUTER
RIGHT OUTER
FULL OUTER
3 CROSS / CARTESIAN JOIN

EQUI JOIN :-
----------

=> To perform equi join between the two tables there must be a common field.

=> name of the common field need not to be same and pk-fk relationship is not
compulsory.

SELECT columns
FROM tab1 INNER JOIN tab2
ON join condition ;

join condition :-
-----------------

=> join condition specifies which record of tab1 joined with which record of tab2
=> based on the given join condition oracle joins the records of two tables

TABLE1.COMMONFIELD = TABLE2.COMMONFIELD

Ex :-

EMP DEPT
EMPNO ENAME SAL DEPTNO DEPTNO DNAME LOC
1 A 3000 10 10 ACCOUNTS NEW YORK
2 B 4000 20 20 RESEARCH
3 C 5000 30 30 SALES
4 D 3000 20 40 OPERATIONS
5 E 2000 NULL

=> display ENAME SAL DNAME LOC ?


----------- -----------
EMP DEPT
SELECT ENAME,SAL,DNAME,LOC
FROM EMP INNER JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO ;

A 3000 ACCOUNTS NEW YORK


B 4000 RESEARCH ?
C 5000 SALES ?
D 3000 RESEARCH ?

NOTE :- in join queries declare table alias prefix column names with
table alias for two reasons

1 to avoid ambiguity
2 for faste execution

SELECT E.ENAME,E.SAL,D.DEPTNO,D.DNAME,D.LOC AS CITY


FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO ;

=> display employees working at NEW YORK loc ?

SELECT E.ENAME,D.DNAME,D.LOC
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO /* join cond */
WHERE D.LOC = 'NEW YORK' /* filter cond */ ;

24-AUG-24

joining more than 2 tables :-


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

=> if no of tables increases no of join conditions also increases.


=> to join N tables N-1 join conditions required.

SELECT columns
FROM tab1 INNER JOIN tab2
ON join cond
INNER JOIN tab3
ON join cond
------- ;

ex :-

EMP DEPT LOCATIONS COUNTRIES

EMPNO DEPTNO LOCID COUNTRY_ID


ENAME DNAME CITY COUNTRY_NAME
SAL LOCID STATE
DEPTNO COUNTRY_ID

=> DISPLAY ENAME DNAME CITY STATE COUNTRY_NAME ?


------ ------ ------------- -------------
EMP DEPT LOCATIONS COUNTRIES

SELECT E.ENAME,
D.DNAME,
L.CITY,L.STATE,
C.COUNTRY_NAME
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
INNER JOIN LOCATIONS L
ON D.LOCID = L.LOCID
INNER JOIN COUNTRIES C
ON L.COUNTRY_ID = C.COUNTRY_ID ;

NON EQUI JOIN :-


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

=> non equi join is performed between the tables not sharing a common field.

=> here join condition is not based on "=" operator and it is based on
> < between operators.

ex :-

EMP SALGRADE
EMPNO ENAME SAL GRADE LOSAL HISAL
1 A 3000 1 700 1000
2 B 1500 2 1001 2000
3 C 2500 3 2001 3000
4 D 5000 4 3001 4000
5 E 1000 5 4001 9999

=> DISPLAY ENAME SAL GRADE ?


--------- -------
EMP SALGRADE

SELECT E.ENAME,E.SAL,S.GRADE
FROM EMP E INNER JOIN SALGRADE S
ON E.SAL BETWEEN S.LOSAL AND S.HISAL ;

A 3000 3
B 1500 2
C 2500 3
D 5000 5
E 1000 1

=> display grade 3 employee list ?

SELECT E.ENAME,E.SAL,S.GRADE
FROM EMP E INNER JOIN SALGRADE S
ON E.SAL BETWEEN S.LOSAL AND S.HISAL
WHERE S.GRADE = 3 ;

=> DISPLAY ENAME DNAME GRADE ?


---- ------ ------
EMP DEPT SALGRADE

SELF JOIN :-
------------

=> joining a table to itself is called self join.

=> in self join a record in one table joined with another record of same table.
=> to perform self join the same table must be declared two times with
different alias.

FROM EMP X INNER JOIN EMP Y

EMP X EMP Y
EMPNO ENAME MGR EMPNO ENAME MGR
7369 SMITH 7902 7369 SMITH 7902
7499 ALLEN 7698 7499 ALLEN 7698
7566 JONES 7839 7566 JONES 7839
7698 BLAKE 7839 7698 BLAKE 7839
7839 KING NULL 7839 KING NULL
7902 FORD 7566 7902 FORD 7566

=> display ENAME MGRNAME ?

SELECT X.ENAME,Y.ENAME AS MANAGER


FROM EMP X INNER JOIN EMP Y
ON X.MGR = Y.EMPNO ;

SMITH FORD
ALLEN BLAKE
JONES KING
BLAKE KING
FORD JONES

=> employees reporting to blake ?

SELECT X.ENAME,Y.ENAME AS MANAGER


FROM EMP X INNER JOIN EMP Y
ON X.MGR = Y.EMPNO
WHERE Y.ENAME='BLAKE' ;

=> blake's manager name ?

SELECT X.ENAME,Y.ENAME AS MANAGER


FROM EMP X INNER JOIN EMP Y
ON X.MGR = Y.EMPNO
WHERE X.ENAME='BLAKE' ;

=> employees earning more than their managers ?

SELECT X.ENAME,X.SAL,
Y.ENAME AS MANAGER,Y.SAL AS MGRSAL
FROM EMP X INNER JOIN EMP Y
ON X.MGR = Y.EMPNO
WHERE X.SAL > Y.SAL ;

26-AUG-24

OUTER JOIN :-
-------------

=> inner join returns only matching records but will not return unmatched
records , to display unmatched records perform outer join.

ex :-
EMP DEPT
EMPNO ENAME SAL DEPTNO DEPTNO DNAME LOC
1 A 3000 10 10 ACCOUNTS NEW YORK
2 B 4000 20 20 RESEARCH
3 C 5000 30 30 SALES
4 D 3000 20 40 OPERATION => unmatched row
5 E 2000 NULL => unmatched row

=> outer join is 3 types

1 LEFT OUTER JOIN


2 RIGHT OUTER JOIN
3 FULL OUTER JOIN

LEFT OUTER JOIN :-


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

=> returns all rows (matched + unmatched) from left side and matching
rows from right side table.

SELECT E.ENAME,D.DNAME
FROM EMP E LEFT OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO ;

=> returns all rows from emp and matching rows from dept

A ACCOUNTS
B RESEARCH
C SALES
D RESEARCH
E NULL => unmatched from emp

RIGHT OUTER JOIN :-


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

=> returns all rows from right side table and matching rows from left side table.

SELECT E.ENAME,D.DNAME
FROM EMP E RIGHT OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO ;

=> returns all rows from dept and matching rows from emp

A ACCOUNTS
B RESEARCH
C SALES
D RESEARCH
NULL OPERATIONS => unmatched from dept

FULL OUTER JOIN :-


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

=> returns all rows from both tables

SELECT E.ENAME,D.DNAME
FROM EMP E FULL OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO ;

=> returns all rows from emp & dept


A ACCOUNTS
B RESEARCH
C SALES
D RESEARCH
E NULL => unmatched from emp
NULL OPERATIONS => unmatched from dept

Displaying only unmatched records :-


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

left side table :-


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

SELECT E.ENAME,D.DNAME
FROM EMP E LEFT OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
WHERE D.DNAME IS NULL ;

E NULL

right side table :-


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

SELECT E.ENAME,D.DNAME
FROM EMP E RIGHT OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
WHERE E.ENAME IS NULL ;

NULL OPERATIONS

both tables :-
-------------

SELECT E.ENAME,D.DNAME
FROM EMP E FULL OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
WHERE D.DNAME IS NULL
OR
E.ENAME IS NULL ;

EX :-

EMP PROJECTS
EMPID ENAME SAL PROJID PROJID PNAME DURATION
1 100 100 A
2 101 101
3 NULL 102

=> display employee details with project details ?

=> display employee details with project details and also display
employees not assigned to any project ?

=> display only the projects where no employee assigned to it ?

CROSS / CARTESIAN JOIN :-


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

=> cross join returns cross product or cartesian product of two tables

A = 1,2
B = 3,4

AXB = (1,3) (1,4) (2,3) (2,4)

=> if cross join performed between two tables then all records of 1st table
joined with all records of 2nd table.

=> to perform cross join submit the join query without join condition

Ex :-

SELECT E.ENAME,D.DNAME
FROM EMP E CROSS JOIN DEPT D ;

Question :-

T1 T2
F1 F1
10 10
20 20
10 10
20 20
NULL NULL
NULL NULL

=> find the count for following operations ?

1 INNER JOIN => 8


2 LEFT OUTER JOIN => 10
3 RIGHT OUTER JOIN => 10
4 FULL OUTER JOIN => 12

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

27-AUG-24

GROUP BY clause :-
------------------

=> GROUP BY clause is used to group rows based on one or more columns
to calculate min,max,sum,avg,count for each group. For example
to calculate dept wise total sal first group the rows based on dept
and apply sum function on each dept.

EMP
EMPNO ENAME SAL DEPTNO
1 A 3000 10
2 B 5000 20 group by 10 9000
3 C 4000 30 =================> 20 8000
4 D 3000 20 30 4000
5 E 6000 10

DETAILED DATA SUMMARIZED DATA


=> GROUP BY clause converts detailed data into summarized data which is
useful for analysis.

syntax :-

SELECT columns
FROM tabname
[WHERE cond]
GROUP BY colname
[HAVING cond]
[ORDER BY col ASC/DESC]

Execution :-

FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

Examples :-

=> display dept wise total salary ?

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

FROM EMP :-
------------

EMP
EMPNO ENAME SAL DEPTNO
1 A 3000 10
2 B 5000 20
3 C 4000 30
4 D 3000 20
5 E 6000 10

GROUP BY DEPTNO :-
-------------------

10 1 A 3000
5 E 6000

20 2 B 5000
4 D 3000

30 3 C 4000

SELECT DEPTNO,SUM(SAL) :-
--------------------------

10 9000
20 8000
30 4000

=> display job wise no of employees ?


SELECT JOB,COUNT(*)
FROM EMP
GROUP BY JOB ;

=> year wise no of employees joined ?

SELECT TO_CHAR(HIREDATE,'YYYY') AS YEAR,COUNT(*)


FROM EMP
GROUP BY TO_CHAR(HIREDATE,'YYYY') ;

SELECT TO_CHAR(HIREDATE,'YYYY') AS YEAR,COUNT(*)


FROM EMP
GROUP BY YEAR => INVALID
ORDER BY YEAR ASC => VALID

NOTE :-

=> column alias cannot be used in group by clause because group by clause
is executed before select.

=> column alias can be used in order by clause because order by is executed
after select.

=> display day wise no of employees joined ?

SELECT TO_CHAR(HIREDATE,'DAY') AS DAY,COUNT(*)


FROM EMP
GROUP BY TO_CHAR(HIREDATE,'DAY') ;

=> display month wise no of employees joined in the year 1981 ?

SELECT TO_CHAR(HIREDATE,'month') AS month,COUNT(*)


FROM EMP
WHERE TO_CHAR(HIREDATE,'YYYY') = 1981
GROUP BY TO_CHAR(HIREDATE,'month') ;

=> find the departments having more than 3 employees ?

SELECT DEPTNO,COUNT(*)
FROM EMP
WHERE COUNT(*) > 3
GROUP BY DEPTNO ; => ERROR

=> oracle cannot calculate dept wise count before group by and it can calculate
only after group by , so apply the condition count(*) > 3 after group by
using having clause.

SELECT DEPTNO,COUNT(*)
FROM EMP
GROUP BY DEPTNO
HAVING COUNT(*) > 3 ;

WHERE VS HAVING :-
------------------

WHERE HAVING
1 selects specific rows selects specific groups

2 conditions applied having conditions applied


before group by after group by

3 use where clause use having clause


if cond doesn't if cond contains
contain group function group function

=> find southern states having more than 5CR population ?

PERSONS
AADHARNO NAME GENDER AGE CITY STATE

SELECT STATE,COUNT(*)
FROM PERSONS
WHERE STATE IN ('AP','TG','TN','KA','KL')
GROUP BY STATE
HAVING COUNT(*) > 50000000 ;

28-AUG-24

Grouping based on more than one column :-


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

=> display dept wise and with in dept job wise total sal ?

SQL>BREAK ON DEPTNO SKIP 1

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

10 CLERK 1300
MANAGER 2450
PRESIDENT 5000

20 ANALYST 6000
CLERK 1900
MANAGER 2975

30 CLERK 950
MANAGER 2850
SALESMAN 5600

=> display year wise with in year quarter wise no of employees joined ?

1981 1 ?
2 ?
3 ?
4 ?

SELECT TO_CHAR(HIREDATE,'YYYY') AS YEAR,TO_CHAR(HIREDATE,'Q') AS QRT,COUNT(*)


FROM EMP
GROUP BY TO_CHAR(HIREDATE,'YYYY'),TO_CHAR(HIREDATE,'Q')
ORDER BY YEAR ASC ;

ROLLUP & CUBE :-


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

=> both functions used to display subtotals and grand total

GROUP BY ROLLUP(COL1,COL2,---)
GROUP BY CUBE(COL1,COL2,-----)

ROLLUP :-
------------

=> rollup displays subtotals for each group and also displays grand total.

SELECT DEPTNO,JOB,SUM(SAL)
FROM EMP
GROUP BY ROLLUP(DEPTNO,JOB)
ORDER BY DEPTNO ASC ;

DEPTNO JOB SUM(SAL)


---------- --------- ----------
10 CLERK 1300
MANAGER 2450
PRESIDENT 5000
8750 => dept subtotal

29025 => grand total

CUBE :-
-------

=> CUBE displays subtotals for each group by column (deptno,job) and also
displays grand total.

SELECT DEPTNO,JOB,SUM(SAL)
FROM EMP
GROUP BY CUBE(DEPTNO,JOB)
ORDER BY DEPTNO ASC ;

DEPTNO JOB SUM(SAL)


---------- --------- ----------
10 CLERK 1300
MANAGER 2450
PRESIDENT 5000
8750 => dept subtotal

ANALYST 6000 => job subtotal


CLERK 4150 => job subtotal

29025 => grand total

GROUPING_ID() :-
----------------

=> grouping_id function takes group by columns and returns subtotal belongs to
which group by column
ex :- GROUPING_ID(DEPTNO,JOB)

1 => subtotal belongs to deptno


2 => subtotal belongs to job
3 => grand total

SELECT DEPTNO,JOB,SUM(SAL),
CASE GROUPING_ID(DEPTNO,JOB)
WHEN 1 THEN 'DEPT SUBTOTAL'
WHEN 2 THEN 'JOB SUBTOTAL'
WHEN 3 THEN 'GRAND TOTAL'
END AS SUBTOTAL
FROM EMP
GROUP BY CUBE(DEPTNO,JOB)
ORDER BY DEPTNO ASC ;

summary :-

importance of group by
queries using group by
where vs having
rollup & cube
grouping_id

GROUP BY & JOIN :-


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

SELECT columns
FROM tab1 INNER JOIN tab2
ON join cond
GROUP BY colname ;

=> display dept wise total sal ? display dept names ?

SELECT D.DNAME,SUM(E.SAL)
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
GROUP BY D.DNAME ;

FROM EMP E INNER JOIN DEPT D :-


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

EMP DEPT
EMPNO ENAME SAL DEPTNO DEPTNO DNAME LOC
1 A 3000 10 10 ACCT
2 B 5000 20 20 RESEARCH
3 C 4000 30 30 SALES
4 D 3000 20 40 OPERATIONS
5 E 6000 10

ON E.DEPTNO = D.DEPTNO :-
---------------------------

1 A 3000 ACCT
2 B 5000 RESEARCH
3 C 4000 SALES
4 D 3000 RESEARCH
5 E 6000 ACCT
GROUP BY D.DNAME :-
------------------

ACCT 1 A 3000
5 E 6000

RESEARCH 2 B 5000
4 D 3000

SALES 3 C 4000

SELECT D.DNAME,SUM(E.SAL) :-
------------------------------

ACCT 9000
RESEARCH 8000
SALES 4000

Question :-

SALES
DATEID CUSTID PRODID QTY AMT
28-AUG-24 10 100 1 2000

PRODUCTS
PRODID PNAME PRICE CATEGORY BRAND
100 AAA 2000 ELECT SAMSUNG

CUST
CUSTID CNAME ADDR COUNTRY
10 KK HYD IND

=> display year wise total amount ?


=> display category wise total amount ?
=> display country wise total amount ?
=> display year wise,country wise,category wise total amount ?

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

29-aug-24

SUB-QUERIES / NESTED QUERIES :-


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

=> a query in another query called sub-query or nested query.


=> one query is called inner/child/sub-query.
=> other query is called outer/parent/main query.
=> first oracle executes inner query then it executes outer query.
=> output of inner query is input to outer query.
=> use sub-query when where cond based on unknown value.

Types of sub-queries :-
--------------------

1 Non co-related
2 co-related
3 INLINE views / CTEs
4 scalar sub-queries

non co-related sub-queries :-


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

SELECT columns
FROM tabname
WHERE colname OP (SELECT STATEMENT) ;

=> OP must be any relational operator like > >= < <= = <>

Examples :-

=> display employees earning more than blake ?

SELECT *
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE ename='BLAKE') ;
----------------------------------------
2850

=> employees who are senior to king ?

SELECT *
FROM emp
WHERE hiredate < ( SELECT hiredate FROM emp WHERE ename='KING') ;
---------------------------------------------
17-NOV-81

=> name of the employee earning max salary ?

SELECT ename
FROM emp
WHERE sal = MAX(sal) ; => ERROR

group functions are not allowed in where clause and they are allowed only in
select,having clauses.

SELECT ename
FROM emp
WHERE sal = (SELECT MAX(sal) FROM emp) ;
---------------------------
5000

=> name of the employee having max experience ?

SELECT ename
FROM emp
WHERE hiredate = (SELECT MIN(hiredate) FROM emp) ;
------------------------------
17-DEC-80

=> display 2nd max sal ?

SELECT MAX(sal)
FROM emp
WHERE sal <> (SELECT MAX(sal) FROM emp) ;
------------------------
5000

=> name of the employee earning 2nd max sal ?

SELECT ename,sal
FROM emp
WHERE sal = (SELECT MAX(sal)
FROM emp
WHERE sal <> (SELECT MAX(sal) FROM emp)) ;

=> delete the employee having max experience ?

DELETE
FROM emp
WHERE hiredate = (SELECT MIN(hiredate) FROM emp) ;

=> swap employee salaries whose empno = 7369,7499 ?

BEFORE SWAP AFTER SWAP

7369 800 7369 1600


7499 1600 7499 800

UPDATE emp
SET sal = CASE empno
WHEN 7369 THEN (SELECT sal FROM emp WHERE empno = 7499)
WHEN 7499 THEN (SELECT sal FROM emp WHERE empno = 7369)
END
WHERE empno IN (7369,7499) ;

UPDATE emp
SET sal = CASE empno
WHEN 7369 THEN 1600
WHEN 7499 THEN 800
END
WHERE empno IN (7369,7499) ;

=> display employee names working at NEW YORK loc ?

sub-query :-
-------------

SELECT ename
FROM emp
WHERE deptno = ( SELECT deptno FROM dept WHERE loc='NEW YORK');

join :-
---------

SELECT e.ename
FROM emp e INNER JOIN dept d
ON e.deptno = d.deptno
WHERE d.loc='NEW YORK' ;

=> display ename & dname working at new york loc ?

join :-
--------

SELECT e.ename,d.dname
FROM emp e INNER JOIN dept d
ON e.deptno = d.deptno
WHERE d.loc='NEW YORK' ;

sub-query :-
------------

not possible

difference between join & subquery ?

1 to display data from one table and condition based on another table then
use sub-query or join

2 to display data from two tables then compulsory use join

=> employees working at NEW YORK,CHICAGO locations ?

SELECT ename
FROM emp
WHERE deptno IN ( SELECT deptno
FROM dept
WHERE loc IN ('NEW YORK','CHICAGO'));

30-AUG-24

CO-RELATED SUB-QUERIES :-
--------------------------

=> if inner query references values of outer query then it is called co-related
sub-query.

=> execution starts from outer query and inner query is executed no of times
depends
on no of rows return by outer query.

=> use co-related sub-query to execute sub-query for each row.

Ex :-

EMP
EMPNO ENAME SAL DEPTNO
1 A 5000 10
2 B 3000 20
3 C 4000 30
4 D 6000 20
5 E 3000 10

=> list of employees earning more than avg sal of the organization ? (not co-
related)

SELECT *
FROM EMP
WHERE SAL > (SELECT AVG(SAL) FROM EMP)
--------------------------
4200

=> list of employees earning more than avg sal of their dept ? (co-related)

SELECT *
FROM EMP X
WHERE SAL > (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = X.DEPTNO) ;

EMP
EMPNO ENAME SAL DEPTNO
1 A 5000 10 5000 > (4000) TRUE
2 B 3000 20 3000 > (4500) FALSE
3 C 4000 30 4000 > (4000) FALSE
4 D 6000 20 6000 > (4500) TRUE
5 E 3000 10 4000 > (4000) FALSE

=> employees earning max sal in their dept ?

SELECT *
FROM EMP X
WHERE SAL = (SELECT MAX(SAL) FROM EMP WHERE DEPTNO = X.DEPTNO) ;

EMP
EMPNO ENAME SAL DEPTNO
1 A 5000 10 5000 = (5000) TRUE
2 B 3000 20 3000 = (6000) FALSE
3 C 4000 30 4000 = (4000) TRUE
4 D 6000 20 6000 = (6000) TRUE
5 E 3000 10 3000 = (5000) FALSE

=> display top 3 max salaries ?

SELECT A.SAL
FROM EMP A
WHERE 3 > (SELECT COUNT(B.SAL)
FROM EMP B
WHERE A.SAL < B.SAL) ;

EMP A EMP B
SAL SAL
5000 5000 3 > (0) TRUE
1000 1000 3 > (4) FALSE
3000 3000 3 > (2) TRUE
2000 2000 3 > (3) FALSE
4000 4000 3 > (1) TRUE

SELECT DISTINCT A.SAL


FROM EMP A
WHERE 3 > (SELECT COUNT(DISTINCT B.SAL)
FROM EMP B
WHERE A.SAL < B.SAL)
ORDER BY SAL DESC ;

EMP A EMP B
SAL SAL
5000 5000 3 > (0) TRUE
4000 4000 3 > (1) TRUE
3000 3000 3 > (2) TRUE
2000 2000 3 > (3) FALSE
4000 4000 3 > (1) TRUE

=> display Nth max sal ?

SELECT DISTINCT A.SAL


FROM EMP A
WHERE (&N-1) = (SELECT COUNT(DISTINCT B.SAL)
FROM EMP B
WHERE A.SAL < B.SAL)
ORDER BY SAL DESC ;

31-aug-24

ROWID :-
--------

=> returns physical address of a row.


=> rowid is called psuedo column because it is not a column but acts like a column

EX :- SELECT ROWID,EMPNO,ENAME,SAL FROM EMP ;

=> ROWIDs are used to delete duplicate records

EMP44
EMPNO ENAME SAL ROWID
1 A 5000 AAA
2 B 6000 AAB
3 C 7000 AAC
1 A 5000 AAD
2 B 6000 AAE

DELETE FROM EMP44 WHERE ROWID LIKE '%AAD' ;

DELETE FROM EMP44 WHERE ROWID LIKE '%AAE' ;

=> deleting duplicates row-by-row is difficult if table contains huge number of


duplicate rows , so execute the following query to delete all duplicate
records

DELETE
FROM EMP44 X
WHERE ROWID <> (SELECT MIN(ROWID)
FROM EMP44
WHERE EMPNO = X.EMPNO
AND
ENAME = X.ENAME
AND
SAL = X.SAL);

EMP44
EMPNO ENAME SAL ROWID
1 A 5000 AAA <> (AAA) FALSE
2 B 6000 AAB <> (AAB) FALSE
3 C 7000 AAC <> (AAC) FALSE
1 A 5000 AAD <> (AAA) TRUE
2 B 6000 AAE <> (AAB) TRUE
INLINE views :-
----------------

=> sub-queries in FROM clause are called inline views.

SELECT columns
FROM (SELECT statement) <ALIAS>
WHERE condition ;

=> sub-query output acts like a table for outer query.

=> INLINE views are used in following scenarios

1 to control order of execution of clauses


2 to join two query outputs

controlling order of execution of clauses :-


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

=> by default oracle executes the clauses in the following order

FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

=> to control this execution order use INLINE views.

SELECT SELECT
FROM ==================================> FROM (SELECT
WHERE FROM
ORDER BY ORDER BY )
WHERE

Example 1 :-

=> display ranks of the employees based on sal and highest paid should get
1st rank ?

SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ;

above query displays ranks of all the employees but to display


top 5 employees

SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP
WHERE RNK <= 5 ; => ERROR

column alias cannot be used in where clause because where clause


is executed before select , to overcome this problem use INLINE views.

SELECT *
FROM ( SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ) E
WHERE RNK<=5 ;

=> display top 5 max salaries ?

SELECT DISTINCT SAL


FROM ( SELECT SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ) E
WHERE RNK<=5 ;

METHODS :-

1 USING FETCH CLAUSE


2 USING CO-RELATED SUB-QUERY
3 USING INLINE VIEWS & DENSE_RANK

2-SEP-24

ROWNUM :-
---------

=> returns record numbers for the records return by select stmt.
=> rownum is also a psuedo column

EX :- SELECT ROWNUM,EMPNO,ENAME,SAL FROM EMP ;

=> rownum is not based on table and it is based on select stmt output ,
if select stmt output changes rownum also changes.

=> rownum is useful when fetching data from table is based on record numbers.

Examples :-

=> display first 5 rows from emp ?

SELECT EMPNO,ENAME,SAL
FROM EMP
WHERE ROWNUM <= 5 ;

=> display 5th row ?

SELECT EMPNO,ENAME,SAL
FROM EMP
WHERE ROWNUM = 5 ;

NOTE :-

In where conditions with rownum = >= operators can't be used ,only


< <= operators can be used. To overcome this problem use INLINE views.

SELECT *
FROM (SELECT ROWNUM AS RNO,EMPNO,ENAME,SAL FROM EMP) E
WHERE RNO = 5 ;

WHERE RNO IN (5,10,15);

WHERE RNO BETWEEN 5 AND 10;


WHERE MOD(RNO,2) = 0;

WHERE MOD(RNO,2) = 1 ;

=> display last 3 rows from emp ?

SELECT *
FROM (SELECT ROWNUM AS RNO,EMPNO,ENAME,SAL FROM EMP) E
WHERE RNO >= (SELECT COUNT(*)-2 FROM EMP);

Question 1 :-

T1 T2
F1 C1
1 A
2 B
3 C

output :-

1 A
2 B
3 C

Question 2 :-

T1
AMT
1000
-200
3000
-800
5000
-500

output :-

POS NEG
1000 -200
3000 -800
5000 -500

SCALAR SUB-QUERIES :-
---------------------

=> sub-queries in SELECT clause are called scalar sub-queries

SELECT (subquery1), (subquery2),----


FROM tabname
WHERE condition ;

=> sub-query output acts like a column for outer query.

Ex 1 :-

SELECT (SELECT COUNT(*) FROM EMP) AS EMP,


(SELECT COUNT(*) FROM DEPT) AS DEPT
FROM DUAL ;
EMP DEPT
14 4

SELECT 14 AS EMP,4 AS DEPT FROM DUAL ;

Ex 2 :-

=> display dept wise total sal ?

SELECT DEPTNO,SUM(SAL) AS DEPT_TOTAL


FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO ASC ;

10 8750
20 10875
30 9400

=> display DEPTNO DEPT_TOTAL TOTAL ?

SELECT DEPTNO,SUM(SAL) AS DEPT_TOTAL,


(SELECT SUM(SAL) FROM EMP) AS TOTAL
FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO ASC ;

10 8750 29025
20 10875 29025
30 9400 29025

=> display DEPTNO DEPT_TOTAL TOTAL PCT ?

PCT = (DEPT_TOTAL/TOTAL)*100

SELECT DEPTNO,SUM(SAL) AS DEPT_TOTAL,


(SELECT SUM(SAL) FROM EMP) AS TOTAL,
ROUND((SUM(SAL) / (SELECT SUM(SAL) FROM EMP))*100,1) AS PCT
FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO ASC

10 8750 29025 30.1


20 10875 29025 37.5
30 9400 29025 32.4

Question :-

SALES
DATEID PRODID CUSTID QTY AMT
02-SEP-24 100 10 1 2000

PRODUCTS
PRODID PNAME PRICE CATEGORY BRAND
100 AAA 2000 ELECTRONICS SAMSUNG

output :-
CATEGORY CAT_TOTAL TOTAL PCT
ELECTRONICS 200 1000 20

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

3-SEP-24

PIVOT operator :-
-----------------

=> operator used to convert rows into columns


=> used for cross tabulation.
=> used to display data in matrix form.

SELECT columns
FROM (SELECT required data) <ALIAS>
PIVOT
(
AGGR-EXP FOR COLNAME IN (V1,V2,V3,---)
)
ORDER BY COLNAME ASC/DESC ;

Ex 1 :-

10 20 30

ANALYST ? ? ?

CLERK ? ? ?

MANAGER ?

SALESMAN

SELECT *
FROM (SELECT DEPTNO,JOB,SAL FROM EMP) E
PIVOT
(
SUM(SAL) FOR DEPTNO IN (10,20,30)
)
ORDER BY JOB ASC ;

Ex 2 :-

1 2 3 4

1980 ? ? ? ?

1981 ? ? ? ?

1982

1983

SELECT *
FROM (SELECT TO_CHAR(HIREDATE,'YYYY') AS YEAR,
TO_CHAR(HIREDATE,'Q') AS QRT,
EMPNO
FROM EMP) E
PIVOT
(
COUNT(EMPNO) FOR QRT IN (1,2,3,4)
)
ORDER BY YEAR ASC ;

Ex 3 :-

STUDENT
SNO SNAME SUBJECT MARKS
1 A MAT 80
1 A PHY 60
1 A CHE 90
2 B MAT 60
2 B PHY 70
2 B CHE 50

output :-

SNO SNAME MAT PHY CHE


1 A 80 60 90
2 B 60 70 50

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

CREATING NEW TABLE FROM EXISTING TABLE (REPLICA) :-


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

CREATE TABLE <TABNAME>


AS
SELECT STATEMENT ;

Ex 1 :- copying complete table

CREATE TABLE EMP11


AS
SELECT * FROM EMP ;

=> a new table is created with name EMP11 and all the rows & cols of emp table
copied to emp11.

Ex 2 :- copying specific rows & cols

CREATE TABLE EMP12


AS
SELECT EMPNO,ENAME,JOB,DEPTNO
FROM EMP
WHERE DEPTNO IN (10,20) ;

Ex 3 :- copy only structure (cols) but not data (rows)

CREATE TABLE EMP13


AS
SELECT * FROM EMP WHERE 1=2 ;
Ex 4 :- copy emp table from batch430 to naresh ?

SYSTEM/MANAGER :-
----------------

SQL>CREATE TABLE NARESH.EMP


AS
SELECT * FROM BATCH430.EMP ;

copying data from one table to another table :-


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

INSERT INTO <TARGET-TABLE>


SELECT COLUMNS FROM <SOURCE-TABLE> ;

Ex :-

=> copy data from emp to emp13 ?

INSERT INTO EMP13


SELECT * FROM EMP ;

MERGE command :-
------------------

=> MERGE is a DML command


=> used to merge data into a table.
=> merge is the combination of insert & update.
=> used to manage replicas.
=> using merge command we can apply changes made to one to another table.

MERGE INTO <TARGET-TABLE>


USING <SOURCE-TABLE>
ON (CONDITION)
WHEN MATCHED THEN
UPDATE
WHEN NOT MATCHED THEN
INSERT ;

Ex :-

STEP 1 :- create source table

CREATE TABLE CUSTS


(
CID NUMBER(2) ,
CNAME VARCHAR2(10),
ADDR VARCHAR2(3)
);

INSERT INTO CUSTS VALUES(1,'A','HYD');


INSERT INTO CUSTS VALUES(2,'B','BLR');

STEP 2 :- create target table

CREATE TABLE CUSTT


AS
SELECT * FROM CUSTS ;
STEP 3 :- modify source table

INSERT INTO CUSTS VALUES(3,'C','DEL');

UPDATE CUSTS SET ADDR='MUM' WHERE CID=1;

STEP 4 :- execute merge command to apply changes to target table

MERGE INTO CUSTT T


USING CUSTS S
ON (S.CID = T.CID)
WHEN MATCHED THEN
UPDATE SET T.ADDR = S.ADDR
WHEN NOT MATCHED THEN
INSERT VALUES(S.CID,S.CNAME,S.ADDR) ;.

CUSTS CUSTT
CID CNAME ADDR CID CNAME ADDR
1 A MUM => U 1 A MUM
2 B BLR 2 B BLR
3 C DEL => I 3 C DEL

Ex 2 :-

EMPS EMPT
EMPNO ENAME SAL EMPNO ENAME SAL
1 A 5000 1 A
2 B 6000 2 B
3 C 7000 3 C

=> copy salaries from emps to empt ?

1 using update command


2 using merge command

04-SEP-24

DATABASE TRANSACTIONS :-
------------------------

=> a transaction is a unit of work that contains one or more dmls


and must be saved as a whole or must be cancelled as a whole.

ex :- money transfer

acct1--------------1000------------------>acct2

update1 update2
(bal=bal-1000) (bal=bal+1000)

successful failed INVALID

failed successful INVALID

successful successful VALID

failed failed VALID


=> every txn must gurantee a property called atomocity i.e. all or none,
if txn contains multiple operations if all are succcessful then it
must be saved , if one of the operation fails then entire txn must
be cancelled.

=> the following commands provided by oracle to handle transactions called


TCL (Transaction Control Lang) commands.

COMMIT => To save txn


ROLLBACK => To cancel txn
SAVEPOINT => To cancel part of the txn

=> every txn has a begin point and and end point

=> a txn begins implicitly with dml command

=> a txn ends when user submits any of the following command

1 COMMIT / ROLLBACK
2 DDL COMMAND (txn ends with commit)

=> if txn ends with COMMIT then it is called successful txn and operations
are saved , if ends with ROLLBACK then it is called aborted txn
and operations are cancelled.

Ex 1 :-

CREATE TABLE A(A NUMBER(2)); => COMMIT


INSERT INTO A VALUES(10); => txn begins T1
INSERT INTO A VALUES(20);
INSERT INTO A VALUES(30);
INSERT INTO A VALUES(40);
ROLLBACK ; => txn ends

CREATE TABLE => saved


INSERTS => cancelled

Ex 2 :-

CREATE TABLE A(A NUMBER(2)); => COMMIT


INSERT INTO A VALUES(10); => txn begins T1
INSERT INTO A VALUES(20);
CREATE TABLE B(B NUMBER(2)); => COMMIT
INSERT INTO A VALUES(30); => txn begins T2
INSERT INTO A VALUES(40);
ROLLBACK ; => txn ends

T1 => SAVED
T2 => CANCELLED

SAVEPOINT :-
------------

=> we can declare savepoint and we can rollback upto the savepoint.
=> using savepoint we can cancel part of the txn.

Ex :-
CREATE TABLE A(A NUMBER(2));
INSERT INTO A VALUES(10);
INSERT INTO A VALUES(20);
SAVEPOINT SP1;
INSERT INTO A VALUES(30);
INSERT INTO A VALUES(40);
SAVEPOINT SP2;
INSERT INTO A VALUES(50);
INSERT INTO A VALUES(60);
ROLLBACK TO SP1 ;

SELECT * FROM A;

10
20
30
40

LOCKING :-
---------

=> accesing same data by no of users at the same time is called concurrent
access , when data accessed concurrently users may encounter following
problems

1 dirty read
2 lost update
3 phantom read
4 non repeatable read

=> to overcome these problems every db system supports a mechanism called


locking mechansim.

=> locks are 2 types / modes

1 SHARED (S)
2 EXCLUSIVE (X)

=> oracle will apply shared lock when we try to read and exclusive lock is
applied when we try to modify the data.

S X

S YES YES

X YES NO

Ex :-

SYSTEM BATCH430

1 UPDATE BATCH430.EMP 2 UPDATE EMP


SET SAL=2000 SET SAL=3000
WHERE EMPNO = 7369 ; WHERE EMPNO = 7369 ;

locked + updated ----wait--------


3 COMMIT; 4 1 ROW UPDATED

lock releases

DEADLOCK :-
-----------

=> Deadlock is the situation where two users mutually waits for one another ,
if deadlock occurs oracle returns error so that one transaction can be
cancelled and continue another transaction.

SYSTEM BATCH430

1 UPDATE BATCH430.EMP 2 UPDATE EMP


SET SAL=2000 SET SAL=3000
WHERE EMPNO = 7369 ; WHERE EMPNO = 7499;

locked + updated locked + updated

3
UPDATE BATCH430.EMP 4 UPDATE EMP
SET SAL=2000 SET SAL=3000
WHERE EMPNO = 7499; WHERE EMPNO = 7369 ;

--------wait------- -------wait--------

============================deadlock=======================================

5 ERROR

6 ROLLBACK; 7 1 row updated

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

DATABASE SECURITY :-
---------------------

USERS => provides security at db level


PRIVILEGES => provides security at table level
VIEWS => provides security at row & col level

SERVER
DATABASE (USER)
TABLE (PRIVILEGES)
ROW & COLS (VIEWS)

CREATING USERS :-
----------------

SYSTEM :-
---------

SQL>CREATE USER VIJAY IDENTIFIED BY ORACLE


DEFAULT TABLESPACE USERS
QUOTA UNLIMITED ON USERS ;
SQL>GRANT CONNECT,RESOURCE TO VIJAY ;

PRIVILEGES :-
-------------

=> privileges means permissions


=> permissions are granted to users by using grant command.

GRANT <privileges> ON <tabname> TO <usernames> ;

BATCH430 :-
------------

SQL>GRANT ALL ON EMP TO VIJAY ;

VIJAY :-
--------

SQL>SELECT * FROM BATCH430.EMP ;

SQL>UPDATE BATCH430.EMP SET SAL=5000 WHERE EMPNO = 7369 ;

changes made by one user visible to another user after commit.

Granting specific privileges :-


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

SQL>GRANT SELECT,INSERT,UPDATE ON DEPT TO VIJAY ;

VIJAY :-
--------

SQL>DELETE FROM BATCH430.DEPT WHERE DEPTNO =10 ; => ERROR

Granting privileges to multiple users :-


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

SQL>GRANT ALL ON EMP TO VIJAY,HR,NARESH ;

SQL>GRANT ALL ON EMP TO PUBLIC ;

PUBLIC => all users

REVOKE command :-
------------------

=> command used to take back permissions from users

REVOKE <privileges> ON <tabname> FROM <usernames>;

BATCH430 :-
----------

SQL>REVOKE ALL ON EMP FROM VIJAY ;

USER_TAB_PRIVS_MADE :-
----------------------

=> stores information about privileges granted to users.


list of privileges granted to user ?

SQL> SELECT PRIVILEGE,TABLE_NAME,GRANTEE


FROM USER_TAB_PRIVS_MADE ;

USER_TAB_PRIVS_RECD :-
---------------------

=> stores information about privileges received.

SELECT PRIVILEGE,TABLE_NAME,GRANTOR
FROM USER_TAB_PRIVS_RECD ;

6-SEP-24

DB OBJECTS :-
------------

1 TABLES
2 VIEWS
3 SYNONYMS
4 SEQUENCES
5 INDEXES

VIEWS :-
--------

=> a view is a subset of a table i.e. part of the table.

=> a view is a virtual table because it doesn't store data and doesn't occupy
memory and it always derives data from base table.

=> a view is representation of a query.

=> views are created

1 to provide security
2 to reduce complexity

=> views are 2 types

1 simple views
2 complex views

simple views :-
---------------

=> a view is said to be simple if it is created on single table.

Granting permission to create view :-


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

SYSTEM :-
--------

SQL>GRANT CREATE VIEW TO BATCH430 ;

BATCH430 :-
------------

SQL>CREATE VIEW V1
AS
SELECT EMPNO,ENAME,JOB,DEPTNO FROM EMP ;

=> oracle creates view "V1" and stores query but not query output.

SELECT * FROM V1 ;

=> oracle executes the above query as follows

SELECT * FROM (SELECT EMPNO,ENAME,JOB,DEPTNO FROM EMP) ;

Granting permissions on view to user :-


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

SQL>GRANT ALL ON V1 TO VIJAY ;

VIJAY :-
---------

SQL>SELECT * FROM BATCH430.V1 ;

SQL>UPDATE BATCH430.V1 SET JOB='MANAGER' WHERE EMPNO = 7369;

SQL>UPDATE BATCH430.V1 SET SAL=3000 WHERE EMPNO = 7369; => ERROR

ROW LEVEL SECURITY :-


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

SQL>CREATE VIEW V2
AS
SELECT EMPNO,ENAME,JOB,DEPTNO
FROM EMP
WHERE DEPTNO = 20 ;

SQL>GRANT ALL ON V2 TO VIJAY ;

complex views :-
----------------

=> a view said to be complex view

1 if based on multiple tables


2 if query performs group by
aggregate
distinct
subquery
set operatios

=> with the help of views complex queries can be converted into simple queries.

Ex 1 :-

CREATE VIEW CV1


AS
SELECT E.EMPNO,E.ENAME,E.SAL,
D.DEPTNO,D.DNAME,D.LOC
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO ;

=> after creating view , whenever we want data from emp & dept tables then
instead of writing join query then write the simple query as follows

SELECT * FROM CV1 ;

Ex 2 :-

CREATE VIEW CV2


AS
SELECT DNAME,MIN(SAL) AS MINSAL,
MAX(SAL) AS MAXSAL,
SUM(SAL) AS TOTSAL,
COUNT(*) AS CNT
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
GROUP BY D.DNAME ;

=> after creating view whenever we want dept wise summary then execute the
following query

SELECT * FROM CV2 ;

difference between simple and complex views ?

simple complex

1 based on single table based on multiple tables

2 query performs simple query performs complex


operations operations like joins,group by etc

3 allows dmls doesn't allow dmls

USER_VIEWS :-
------------

=> stores views created by user

=> list of views created by user ?

SELECT VIEW_NAME FROM USER_VIEWS ;

=> display the query associated with CV2 ?

SELECT TEXT FROM USER_VIEWS WHERE VIEW_NAME='CV2' ;

Droping :-
-----------

DROP VIEW V1 ;

if we drop table what about views created on table ?

ANS :- views are not dropped , if views cannot be queried


SYNONYMS :-
----------

=> a synonym is another name or alternative name for a table or view.

=> If tablename is lengthy then we can give a simple and short name to the
table called synonym and instead of using table name we can use
synonym name in SELECT/INSERT/UPDATE/DELETE queries.

Granting permissions to create synonym :-


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

SYSTEM :-
---------

SQL>GRANT CREATE SYNONYM TO BATCH430;

BATCH430 :-
----------

SQL>CREATE SYNONYM E FOR EMP ;

after creating synonym instead of using table name use synonym name in
SELECT / INSERT / UPDATE / DELETE queries.

SQL>SELECT * FROM E ;

SQL>UPDATE E SET COMM = 500 WHERE EMPNO = 7369 ;

Accessing tables without owner name :-


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

BATCH430 :-
----------

SQL>GRANT ALL ON EMP TO VIJAY ;

VIJAY :-
---------

SQL>SELECT * FROM BATCH430.EMP ;

SQL>CREATE SYNONYM EMP FOR BATCH430.EMP ;

SQL>SELECT * FROM EMP ;

QUESTION :-
-----------

SQL>CREATE SYNONYM E FOR EMP ;

SQL>SELECT * FROM EMP E;

SQL>RENAME EMP TO E ;

difference between synonyms and alias ?

synonym alias
1 permanent not permanent

2 stored in db not stored in db

3 scope of the synonym scope of the alias is


is upto the schema(user) upto the query

USER_SYNONYMS :-
-----------------

=> stores list of synonyms created by user.

SELECT SYNONYM_NAME,TABLE_NAME FROM USER_SYNONYMS ;

Droping :-
---------

SQL>DROP SYNONYM E ;

if we drop table what about synonyms created on table ?

ANS :- synonyms are not dropped but becomes invalid

Question :-
-------------

SQL> DROP TABLE PRODUCTS ;

what is the implication of this command

A drops table structure along with data T


B any pending transaction in session is committed T
C drops views & synonyms created on table F
D views & synonyms are not dropped but becomes invalid T
E drops only data but keeps structure F

SEQUENCES :-
-------------

=> a sequence is also a db object created to generate sequence numbers.


=> used to auto increment column values.

CREATE SEQUENCE <NAME>


[START WITH value]
[INCREMENT BY value]
[MAXVALUE value]
[MINVALUE value]
[CYCLE]
[CACHE size] ;

Ex 1 :-

SQL>CREATE SEQUENCE S1
START WITH 1
INCREMENT BY 1
MAXVALUE 5 ;
using sequence :-
------------------

SQL>CREATE TABLE STUDENT(SID NUMBER(2),SNAME VARCHAR2(10));

use sequence s1 to generate values for sid ?

SQL>INSERT INTO STUDENT VALUES(S1.NEXTVAL,'A');


SQL>INSERT INTO STUDENT VALUES(S1.NEXTVAL,'B');
SQL>INSERT INTO STUDENT VALUES(S1.NEXTVAL,'C');
SQL>INSERT INTO STUDENT VALUES(S1.NEXTVAL,'D');
SQL>INSERT INTO STUDENT VALUES(S1.NEXTVAL,'E');
SQL>INSERT INTO STUDENT VALUES(S1.NEXTVAL,'F'); => ERROR

SQL>SELECT * FROM STUDENT ;

SID SNAME
---------- ----------
1 A
2 B
3 C
4 D
5 E

Ex 2 :-

SQL>CREATE SEQUENCE S2
START WITH 100
INCREMENT BY 1
MAXVALUE 999;

use above sequence to generate empnos ?

SQL>UPDATE EMP SET EMPNO = S2.NEXTVAL ;

10-SEP-24

Ex 3 :-

BILL
BILLNO BDATE AMOUNT
DMART/0924/1
/2

CREATE SEQUENCE S5
START WITH 1
INCREMENT BY 1
MAXVALUE 9999;

CREATE TABLE BILL


(
BILLNO VARCHAR2(20),
BDATE DATE,
AMOUNT NUMBER(6)
);

INSERT INTO BILL


VALUES('DMART/'||
TO_CHAR(SYSDATE,'MMYY')||'/'||S5.NEXTVAL,SYSDATE,1000);

CYCLE :-
---------

=> by default sequence is created with NOCYCLE.

=> if sequence created with CYCLE then it starts from start with
and generates upto max and after reaching max then it will be
reset to min.

CREATE SEQUENCE S10


START WITH 1
INCREMENT BY 1
MAXVALUE 5
MINVALUE 1
CYCLE
CACHE 4 ;

CACHE size :-
-------------

CREATE SEQUENCE S20


START WITH 1
INCREMENT BY 1
MAXVALUE 1000
MINVALUE 1
CYCLE
CACHE 100 ;

=> oracle preallocates next 100 values in cache memory , when we call
seq.nextval oracle goes to cache memory and gets the value and
returns the value from cache memory and accessing cache memory
is much faster than accessing db , so this improves performance.

=> default cache size is 20.

=> cache size must be less than 1 cycle.

CREATE SEQUENCE S11


START WITH 1
INCREMENT BY 1
MAXVALUE 10
MINVALUE 1
CYCLE ;

=> above command returns error when executed what could be the reason ?

ans :- cache size must be less than 1 cycle.

USER_SEQUENCES :-
----------------

=> stores information about sequences created by user.

SELECT MIN_VALUE,MAX_VALUE,INCREMENT_BY,CYCLE_FLAG,CACHE_SIZE
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME='S50' ;
MIN_VALUE MAX_VALUE INCREMENT_BY C CACHE_SIZE
---------- ---------- ------------ - ----------
1 1.0000E+28 1 N 20

changing sequence parameters :-


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

SQL>ALTER SEQUENCE S50 MAXVALUE 10;

SQL>ALTER SEQUENCE S50 CYCLE ; => ERROR

SQL>ALTER SEQUENCE S50 CACHE 5 ;

SQL>ALTER SEQUENCE S50 CYCLE ;

Droping :-
----------

SQL>DROP SEQUENCE S1 ;

INDEX :-
-------

=> index is also a db object created to improve performance.

=> index in db is similar to index in text book , In text book


using index a particular topic can be located fastly , In db
using index a particular record can be located fastly.

=> indexes created on columns that column is called index key.

Types of Indexes :-
--------------------

1 BTREE indexes
simple
unique
2 BITMAP indexes

simple btree index :-


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

CREATE INDEX I1 ON EMP(SAL);

EMP 3000
SAL
3000
1000
1500 2000 4000
4000
3000 1000 * 2500 * 4000 * 5000 *
2500 1500 * 3000 *,*
2000 2000 *
5000

SELECT * FROM EMP WHERE SAL = 3000 ; (INDEX SCAN)


SELECT * FROM EMP WHERE SAL >= 3000 ; (INDEX SCAN)
SELECT * FROM EMP WHERE SAL <= 3000 ; (INDEX SCAN)

SELECT * FROM EMP WHERE SAL <> 3000 ; (TABLE SCAN)


SELECT * FROM EMP WHERE ENAME='BLAKE' ; (TABLE SCAN)
SELECT * FROM EMP ; (TABLE SCAN)

command to see the execution plan :-


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

SQL>SET AUTOTRACE ON EXPLAIN

UNIQUE INDEX :-
--------------

=> unique index doesn't allow duplicate values into the column on which
index is created.

CREATE UNIQUE INDEX I2 ON EMP(ENAME) ;

G Q

ADAMS * JAMES * MARTIN * SCOTT *


ALLEN * JONES * MILLER * SMITH *
BLAKE *

=> SELECT * FROM EMP WHERE ENAME='BLAKE' ;

=> INSERT INTO EMP(EMPNO,ENAME,SAL) VALUES(999,'BLAKE',4000); => ERROR

what are the different methods to enforce uniqueness ?

1 declare pk / unique constraint


2 create unique index

NOTE :-

=> pk / unique columns are indexed by oracle.

=> oracle creates a unique index on pk/unique columns and unique


index doesn't allow duplicates , so pk/unique also doesn't allow
duplicates.

BITMAP indexes :-
------------------

=> BITMAP indexes created on low cardinality columns i.e. columns that contains
less distinct values (<200).

EX :- JOB,DEPTNO,GENDER

=> bitmap index stores bits.

Ex :-

SQL>CREATE BITMAP INDEX BI1 ON EMP(GENDER);

SQL>CREATE BITMAP INDEX BI2 ON EMP(JOB);


BI1(GENDER) EMP BI2(JOB)
M F GENDER JOB CLERK MANAGER SALESMAN
1 0 M CLERK 1 0 0
0 1 F MANAGER 0 1 0
1 0 M SALESMAN 0 0 1
0 1 F CLERK 1 0 0
1 0 M MANAGER 0 1 0
1 0 M SALESMAN 0 0 1

SELECT * FROM EMP WHERE GENDER='M' ;

SELECT * FROM EMP WHERE JOB='CLERK' ;

=> for the above query oracle goes index BI2 and checks clerk bit is
1 or 0 , if bit = 1 then corresponding record selected from table ,
if bit = 0 record is not selected.

difference between btree and bitmap indexes ?

BTREE BITMAP

1 recommended on high cardinality recommended on low cardinality


columns columns

2 stores index key values stores bits

3 stroes rowids doesn't store rowids

USER_INDEXES :-
---------------

=> stores indexes created by user

list of indexes created on EMP table ?

SELECT INDEX_NAME,INDEX_TYPE
FROM USER_INDEXES
WHERE TABLE_NAME='EMP' ;

Droping :-
------------

SQL>DROP INDEX I1 ;

if we drop table what about indexes created on table ?

ANS :- indexes are also dropped

SERVER
DATABASE
USER
TABLE
ROWS & COLS
CONSTRAINTS
INDEXES
TRIGGERS
VIEW
SYNONYM
SEQUENCE

SQL

COMMANDS CLAUSES OPERATIONS OBJECTS

DDL WHERE FILTERING TABLES


DML ORDER BY SORTING VIEWS
DQL DISTINCT ELIMINATING DUPLICATES SYNONYMS
TCL FETCH TOP N ROWS SEQUENCES
DCL GROUP BY GROUPING INDEXES
HAVING FILTERING
ON JOIN
SET OPERATIONS
SUB-QUERIES
FUNCTIONS

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

PL/SQL
======

PL => PROCEDURAL LANG

ORACLE

SQL PL/SQL
NON - PROC PROC
COMMANDS BLOCKS

FEATURES :-
------------

1 improves performance :-
----------------------

=> In pl/sql , sql commands can be grouped into one block and we submit that
block
to oracle , so in pl/sql no of requests and response between user and oracle
are reduced and performance is improved.

2 supports conditional statements :-


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

=> PL/SQL supports conditional statements like IF-ELSE, so in pl/sql we can


execute
sql commands based on conditions.

3 supports loops :-
-----------------

=> PL/SQL supports looping statements like WHILE,FOR etc and with the help of
loops
we can execute sql commands repeatedly multiple times.
4 supports error handling :-
--------------------------

=> In pl/sql if any statement causes error then we can handle that error
and we can replace system generated message with our own simple
and user friendly message.

5 supports reusability :-
-----------------------

=> PL/SQL programs can be stored in db and applications which are connected
to db can reuse pl/sql programs.

6 supports security :-
-------------------

=> In pl/sql we can create procedures & functions and we can grant
permissions on proc & func to users and users can access
db only through proc & func.

=> PL/SQL blocks are 2 types

1 Anonymous Blocks
2 Named Blocks
procedures
functions
packages
triggers

Anonymous Blocks :-
-------------------

=> PL/SQL programs without name are called anonymous blocks.

DECLARE
<declaration-part>; OPTIONAL
BEGIN
statements;
END;
/ => compiled & executed

How to print messages :-


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

DBMS_OUTPUT.PUT_LINE(MESSAGE);
----------- --------
PACKAGE PROCEDURE

=> by default messages are not send to output , to send messages to output
execute the following command

SQL>SET SERVEROUTPUT ON

13-SEP-24

How to write programs :-


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

1 EDITORS
2 IDEs (Integrated Development Environment)

EDITOR IDE

CODING YES YES

COMPILING NO YES

EXECUTING NO YES

DEBUGGING NO YES

EXAMPLE NOTEPAD SQL DEVELOPER

using notepad :-
---------------

=> open notepad and enter following code

BEGIN
DBMS_OUTPUT.PUT_LINE('HELLO WELCOME');
END;
/

=> save the program in a file as C:\ORACLE\"PROG1.SQL"

=> go to sqlplus and compile and run the program as follows.

SQL>@C:\ORACLE\"PROG1.SQL"

o/p :- HELLO WELCOME

Datatypes in PL/SQL :-
---------------------

1 scalar types or built-in types


2 user define types
3 reference types

SCALAR TYPES OR BUILT-IN TYPES :-


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

1 NUMBER(P) / NUMBER(P,S)
2 CHAR/VARCHAR2/LONG/CLOB
3 NCHAR/NVARCHAR2/NCLOB
4 DATE / TIMESTAMP
5 BFILE / BLOB
6 BINARY_FLOAT / BINARY_DOUBLE
7 BINARY_INTEGER
8 BOOLEAN

1 TO 6 => allowed in SQL, PL/SQL


7,8 => allowed only in PL/SQL but not allowed in SQL.

Declaring variable :-
----------------------
VARIABLENAME DATATYPE(SIZE);

Ex :-

X NUMBER(4);
S VARCHAR2(10);
D DATE;
B BOOLEAN;

Assigning value to variable :-


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

VARIABLENAME := VALUE ; = comparision


:= assignment

Ex :-

X := 100;
S := 'HELLO';
D := SYSDATE;
B := TRUE;

=> wap to add two numbers ?

DECLARE
a NUMBER(4);
b NUMBER(4);
c NUMBER(5);
BEGIN
a := 100;
b := 200;
c := a+b;
DBMS_OUTPUT.PUT_LINE(c);
END;
/

How to input values at runtime :-


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

1 a := &a;

enter value for a :- 100

a := 100;

2 a := &x;

enter value for x :- 200

a := 200;

DECLARE
a NUMBER(4);
b NUMBER(4);
c NUMBER(5);
BEGIN
a := &a;
b := &b;
c := a+b;
DBMS_OUTPUT.PUT_LINE(c);
END;
/

VERIFY :-
-------

SET VERIFY ON => displays old & new statements


SET VERIFY OFF => will not display old & new statements

=> wap to input date and print day of the week ?

DECLARE
d DATE;
BEGIN
d := '&date';
DBMS_OUTPUT.PUT_LINE(TO_CHAR(d,'day'));
END;
/

Enter value for date: 01-JAN-2025

o/p :- wednesday

=> wap to input name and print first name,middle name,last name ?

n = SACHIN RAMESH TENDULKAR

SUBSTR(STRING,START,[NO OF CHARS])
INSTR(STRING,CHAR,[START,OCCURANCE])

DECLARE
n VARCHAR2(30);
f VARCHAR2(20);
m VARCHAR2(20);
l VARCHAR2(20);
BEGIN
n := '&name';
f := SUBSTR(n,1,INSTR(n,' ')-1);
l := SUBSTR(n,INSTR(n,' ',1,2)+1);
m := TRIM(RTRIM(LTRIM(n,f),l)) ;
DBMS_OUTPUT.PUT_LINE('First Name = '||f);
DBMS_OUTPUT.PUT_LINE('Middle Name = '||m);
DBMS_OUTPUT.PUT_LINE('Last Name = '||l);
END;
/

o/p :-

First Name = ??
Middle Name = ??
Last Name = ??

14-sep-24

REGEXP_SUBSTR() :-
------------------

=> used to get part of the string based on pattern


REGEXP_SUBSTR(STRING,PATTERN,START,OCCURANCE);

Ex :-

REGEXP_SUBSTR('ABC123XYZ456','[0-9]',1,1) => 1
REGEXP_SUBSTR('ABC123XYZ456','[0-9]+',1,1) => 123
REGEXP_SUBSTR('ABC123XYZ456','[0-9]+',1,2) => 456
REGEXP_SUBSTR('ABC123XYZ456','[A-Z]+',1,1) => ABC

n = SACHIN RAMESH TENDULKAR

DECLARE
n VARCHAR2(30);
f VARCHAR2(20);
m VARCHAR2(20);
l VARCHAR2(20);
BEGIN
n := '&name';
f := REGEXP_SUBSTR(n,'[A-Z]+',1,1);
l := REGEXP_SUBSTR(n,'[A-Z]+',1,2);
m := REGEXP_SUBSTR(n,'[A-Z]+',1,3);
DBMS_OUTPUT.PUT_LINE('First Name = '||f);
DBMS_OUTPUT.PUT_LINE('Middle Name = '||m);
DBMS_OUTPUT.PUT_LINE('Last Name = '||l);
END;
/

DB PROGRAMMING WITH PL/SQL :-


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

=> From pl/sql to work with db execute sql commands from pl/sql program.
=> the following commands can be executed from pl/sql program.

1 DML (INSERT,UPDATE,DELETE,MERGE,INSERT ALL)


2 DQL (SELECT)
3 TCL (COMMIT,ROLLBACK,SAVEPOINT)

SELEC stmt syntax :-


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

SELECT columns INTO variables


FROM tabname
WHERE condition ;

Ex :-

SELECT ename,sal INTO n,s


FROM emp
WHERE empno = 7844 ;

=> wap to input empno and print name & sal ?

DECLARE
vempno NUMBER(4);
vename VARCHAR2(10);
vsal NUMBER(7,2);
BEGIN
vempno := &empno;
SELECT ename,sal INTO vename,vsal
FROM emp
WHERE empno = vempno;
DBMS_OUTPUT.PUT_LINE(vename||' '||vsal);
END;
/

=> wap to input empno and calculate and print experience ?

DECLARE
vempno NUMBER(4);
vhire DATE;
vexpr NUMBER(2);
BEGIN
vempno := &empno;
SELECT hiredate INTO vhire
FROM emp
WHERE empno = vempno ;
vexpr := (SYSDATE-vhire)/365;
DBMS_OUTPUT.PUT_LINE('EXPERIENCE = '||vexpr||' YEARS');
END;
/

Enter value for empno: 7566

EXPERIENCE = 43 YEARS

Question :-

=> wap to input cid and find fname,mname,lname and insert into CUSTT table ?

CUSTS CUSTT
CID CNAME CID FNAME MNAME LNAME
10 SACHIN RAMESH TENDULKAR
11 MAHENDRA SINGH DHONI

Conditional statements :-
-------------------------

1 SIMPLE IF
2 MULTI IF
3 NESTED IF

SIMPLE IF :-
------------

IF COND THEN
statements;
ELSE
statements;
END IF;

MULTI IF :-
------------

IF COND1 THEN
statements;
ELSIF COND2 THEN
statements;
ELSIF COND3 THEN
statements;
ELSE
statements;
END IF;

NESTED IF :-
-----------

IF COND THEN
IF COND THEN
statements;
ELSE
statements;
END IF;
ELSE
statements;
END IF;

16-SEP-24

=> write a prog to input empno and increment salary by specific amount
and after increment if sal exceeds 5000 then cancel that increment ?

DECLARE
vempno NUMBER(4);
vamt NUMBER(6);
vsal NUMBER(7,2);
BEGIN
vempno := &empno;
vamt := &amount;
UPDATE emp SET sal = sal + vamt WHERE empno = vempno;
SELECT sal INTO vsal FROM emp WHERE empno = vempno;
IF vsal > 5000 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END;
/

=> wap to input empno and increment sal as follows ?

if job=CLERK incr sal by 10%


SALESMAN 15%
MANAGER 20%
others 5%

DECLARE
vempno NUMBER(4);
vjob VARCHAR2(10);
vpct NUMBER(2);
BEGIN
vempno := &empno;
SELECT job INTO vjob FROM emp WHERE empno = vempno ;
IF vjob='CLERK' THEN
vpct := 10;
ELSIF vjob='SALESMAN' THEN
vpct := 15;
ELSIF vjob='MANAGER' THEN
vpct := 20;
ELSE
vpct := 5;
END IF;
UPDATE emp SET sal = sal + (sal*vpct/100) WHERE empno = vempno;
COMMIT;
END;
/

=> wap to process bank transaction (W/D) ?

ACCOUNTS
ACCNO ACTYPE BAL
100 S 10000
101 C 20000

TRANSACTIONS
TRID TTYPE TDATE TAMT ACCNO

CREATE SEQUENCE S1
START WITH 1
INCREMENT BY 1
MAXVALUE 9999;

CREATE TABLE ACCOUNTS


(
ACCNO NUMBER(4) PRIMARY KEY,
ACTYPE CHAR(1),
BAL NUMBER(10,2)
);

INSERT INTO ACCOUNTS VALUES(100,'S',10000);


INSERT INTO ACCOUNTS VALUES(101,'S',20000);

CREATE TABLE TRANSACTIONS


(
TRID NUMBER(5),
TTYPE CHAR(1),
TDATE DATE,
TAMT NUMBER(5),
ACCNO NUMBER(4) REFERENCES ACCOUNTS(ACCNO)
);

DECLARE
vacno NUMBER(4);
vtype CHAR(1);
vamt NUMBER(5);
vbal NUMBER(10,2);
BEGIN
vacno := &acno;
vtype := '&type';
vamt := &amount;
IF vtype='W' THEN
SELECT bal INTO vbal FROM accounts WHERE accno = vacno;
IF vamt > vbal THEN
DBMS_OUTPUT.PUT_LINE('insufficient balance');
ELSE
UPDATE accounts SET bal = bal-vamt WHERE accno = vacno;
INSERT INTO transactions VALUES(S1.NEXTVAL,'W',SYSDATE,vamt,vacno);
COMMIT;
END IF;
ELSIF vtype='D' THEN
UPDATE accounts SET bal = bal+vamt WHERE accno = vacno;
INSERT INTO transactions VALUES(S1.NEXTVAL,'D',SYSDATE,vamt,vacno);
COMMIT;
ELSE
DBMS_OUTPUT.PUT_LINE('invalid transaction type');
END IF;
END;
/

17-SEP-24

=> wap for money transfer ?

DECLARE
vsacno NUMBER(4);
vtacno NUMBER(4);
vamt NUMBER(6);
vbal NUMBER(10,2);
BEGIN
vsacno := &sacno;
vtacno := &tacno;
vamt := &amount;
SELECT bal INTO vbal FROM accounts WHERE accno = vsacno;
IF vamt > vbal THEN
DBMS_OUTPUT.PUT_LINE('insufficient balance');
ELSE
UPDATE accounts SET bal = bal - vamt WHERE accno = vsacno;
UPDATE accounts SET bal = bal + vamt WHERE accno = vtacno;
INSERT INTO transactions VALUES(S1.NEXTVAL,'W',sysdate,vamt,vsacno);
INSERT INTO transactions VALUES(S1.NEXTVAL,'D',sysdate,vamt,vtacno);
COMMIT;
END IF;
END;
/

Reference Types :-
------------------

1 %TYPE
2 %ROWTYPE

%TYPE :-
---------

=> used to refer column type & size.


=> used to match variable type & size with column type & size.

Ex :- vsal emp.sal%TYPE;

=> whatever datatype & size declared for sal column the same type and size
assigned to variable vsal.

=> Adv of %TYPE is even if column type or size changes pl/sql program is not
affected.

%ROWTYPE :-
-----------

=> used to refer record type


=> a variable declared with %ROWTYPE is called record type variable.
=> In rowtype variable we can store row.

ex :- r emp%ROWTYPE;

SELECT * INTO r FROM emp WHERE empno = 7844 ;

r
empno ename job mgr hiredate sal comm deptno
7844 TURNER SALESMAN 8-SEP-81 1500 0 30

r.sal => 1500


r.ename => TURNER
r.job => SALESMAN

=> Adv of %ROWTYPE is it reduces no of variable required in the program and


reduces complexity.

Ex :-

STUDENT
SNO SNAME S1 S2 S3
1 A 80 90 70
2 B 30 60 50

RESULT
SNO TOTAL AVG RESULT

=> WAP to input sno and calculate total,avg,result and insert into result table ?

DECLARE
vsno student.sno%TYPE;
s student%ROWTYPE;
r result%ROWTYPE;
BEGIN
vsno := &sno;
SELECT * INTO s FROM student WHERE sno = vsno ;
r.total := s.s1 + s.s2 + s.s3;
r.avg := r.total/3;
IF s.s1>=35 AND s.s2>=35 AND s.s3>=35 THEN
r.result := 'PASS';
ELSE
r.result := 'FAIL';
END IF;
INSERT INTO result VALUES(vsno,r.total,r.avg,r.result);
COMMIT;
END;
/

s
SNO SNAME S1 S2 S3
1 A 80 90 70

r
SNO TOTAL AVG RESULT
240 80 PASS

LOOPS :-
--------

=> loops are used to execute statements repeatedly multiple times


=> pl/sql supports 3 types of loops

1 simple loop
2 while loop
3 for loop

simple loop :-
------------

LOOP LOOP
statements; statements;
EXIT WHEN COND; IF COND THEN
END LOOP; EXIT;
END IF;
END LOOP;

=> if cond = false loop continues


=> if cond = true loop terminates

WHILE loop :-
-------------

WHILE(cond)
LOOP
statements;
END LOOP;

if cond = true loop continues


if cond = false loop terminates

FOR loop :-
----------

FOR var IN low..upp


LOOP
statements;
END LOOP;

Ex :-

FOR i IN 1..10
LOOP
statments;
END LOOP;

=> loop variable "i" declared implicitly as number type.


=> by default "i" value is incremented by 1
=> "i" is read only variable.
=> scope of the "i" is upto the for loop.

Examples :-

=> WAP to print numbers from 1 to 20 ?

using simple loop :-


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

DECLARE
x NUMBER(2) := 1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(x);
x := x+1;
EXIT WHEN x > 20;
END LOOP;
END;
/

using while loop :-


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

DECLARE
x NUMBER(2) := 1;
BEGIN
WHILE(x<=20)
LOOP
DBMS_OUTPUT.PUT_LINE(x);
x := x+1;
END LOOP;
END;
/

using FOR loop :-


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

BEGIN
FOR x IN 2..20
LOOP
DBMS_OUTPUT.PUT_LINE(x);
END LOOP;
END;
/

18-sep-24

=> wap to print 2024 calendar ?

01-JAN-24 ?
02-JAN-24 ?

31-DEC-24 ?

DECLARE
d1 DATE;
d2 DATE;
BEGIN
d1 := '01-JAN-24' ;
d2 := '31-DEC-24' ;
WHILE(d1<=d2)
LOOP
DBMS_OUTPUT.PUT_LINE(d1||' '||TO_CHAR(d1,'day'));
d1 := d1+1;
END LOOP;
END;
/

=> wap to print sundays between two given dates ?

DECLARE
d1 DATE;
d2 DATE;
BEGIN
d1 := '01-JAN-24' ;
d2 := '31-DEC-24' ;
d1 := NEXT_DAY(d1,'sunday');
WHILE(d1<=d2)
LOOP
DBMS_OUTPUT.PUT_LINE(d1||' '||TO_CHAR(d1,'day'));
d1 := d1+7;
END LOOP;
END;
/

=> wap to input string and print following pattern ?

input :- NARESH

output
N
A
R
E
S
H

DECLARE
s VARCHAR2(10);
BEGIN
s := '&string' ;
FOR i IN 1..LENGTH(s)
LOOP
DBMS_OUTPUT.PUT_LINE(SUBSTR(s,i,1));
END LOOP;
END;
/

=> wap to input string and print following pattern ?

input :- NARESH

output :-

N
NA
NAR
NARE
NARES
NARESH

DECLARE
s VARCHAR2(10);
BEGIN
s := '&string' ;
FOR i IN 1..LENGTH(s)
LOOP
DBMS_OUTPUT.PUT_LINE(SUBSTR(s,1,i));
END LOOP;
END;
/

=> wap to input string and print reverse ?

INPUT :- NARESH
OUTPUT :- HSERAN

DECLARE
s1 VARCHAR2(10);
s2 VARCHAR2(10);
BEGIN
s1 := '&string' ;
FOR i IN 1..LENGTH(s1)
LOOP
s2 := s2||SUBSTR(s1,-i,1);
END LOOP;
DBMS_OUTPUT.PUT_LINE(s2);
IF s1=s2 THEN
DBMS_OUTPUT.PUT_LINE('palindrome');
ELSE
DBMS_OUTPUT.PUT_LINE('not a palindrome');
END IF;
END;
/

CURSORS :-
----------

=> cursors are used to processs multiple rows in pl/sql program.

=> using cursor we can access row-by-row in pl/sql program.

=> from pl/sql prog if we submit a query to oracle , it goes to


db and gets the data and copies that data into temporary memory
called cursor. In program we can give name to cursor and
access row-by-row from cursor and process the row.

=> follow below steps to use cursor in pl/sql program.

1 DECLARE CURSOR
2 OPEN CURSOR
3 FETCH RECORD FROM CURSOR
4 CLOSE CURSOR

Declaring cursor :-
-------------------
CURSOR <NAME> IS SELECT STATEMENT ;

EX :- CURSOR C1 IS SELECT ENAME,SAL FROM EMP ;

Opening cursor :-
----------------

OPEN <cursor-name>;

Ex :- OPEN C1;

1 select stmt declared with cursor submitted to oracle


2 data returned by query is copied to cursor
3 c1 points to cursor

Fetching record from cursor :-


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

=> "FETCH" stmt is used to fetch record from cursor

FETCH <name> INTO <variables>;

Ex:- FETCH C1 INTO vename,vsal ;

=> a FETCH stmt fetches one row at a time but to process multiple rows
fetch stmt should be executed multiple times , so fetch should be
in a loop.

Closing cursor :-
------------------

CLOSE <cursor-name>;

Ex :- CLOSE C1 ;

19-SEP-24

CURSOR ATTRIBUTES :-
--------------------

%FOUND :-
---------

TRUE => IF FETCH SUCCESSFUL


FALSE => IF FETCH UNSUCCESSFUL

%NOTFOUND :-
------------

TRUE => IF FETCH UNSUCCESSFUL


FALSE => IF FETCH SUCCESSFUL

%ROWCOUNT :-
-------------

=> returns no of rows fetched successfully


C1%FOUND
C1%NOTFOUND
C1%ROWCOUNT

Examples :-

=> WAP to print all employee names and salaries ?

DECLARE
CURSOR C1 IS SELECT ename,sal FROM emp ;
vename emp.ename%TYPE;
vsal emp.sal%TYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO vename,vsal;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(vename||' '||vsal);
END LOOP;
CLOSE C1;
END;
/

using while loop :-


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

DECLARE
CURSOR C1 IS SELECT ename,sal FROM emp ;
vename emp.ename%TYPE;
vsal emp.sal%TYPE;
BEGIN
OPEN C1;
FETCH C1 INTO vename,vsal;
WHILE(C1%FOUND)
LOOP
DBMS_OUTPUT.PUT_LINE(vename||' '||vsal);
FETCH C1 INTO vename,vsal;
END LOOP;
CLOSE C1;
END;
/

FOR LOOP CURSOR :-


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

FOR <var> IN <cursor-name>


LOOP
statements;
END LOOP;

Ex :-

FOR r IN C1
LOOP
statements;
END LOOP;

=> FOR loop is executed no of times depends on no of rows in cursor.


=> every time for loop executes a row is fetched from cursor and copied to
variable "r".

=> loop variable "r" is also declared implicitly as rowtype.

DECLARE
CURSOR C1 IS SELECT ename,sal FROM emp;
BEGIN
FOR r IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(r.ename||' '||r.sal);
END LOOP;
END;
/

=> wap to calculate total sal without using sum function ?

DECLARE
CURSOR C1 IS SELECT sal FROM emp ;
t NUMBER := 0;
BEGIN
FOR r IN C1
LOOP
t := t + r.sal;
END LOOP;
DBMS_OUTPUT.PUT_LINE(t);
END;
/

=> wap to find max sal without using max function ?

DECLARE
CURSOR C1 IS SELECT sal FROM emp ;
m NUMBER := 0;
BEGIN
FOR r IN C1
LOOP
IF r.sal > m THEN
m := r.sal;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(m);
END;
/

DECLARE
CURSOR C1 IS SELECT sal FROM emp ORDER BY sal DESC;
vsal emp.sal%TYPE;
BEGIN
OPEN C1;
FETCH C1 INTO vsal;
DBMS_OUTPUT.PUT_LINE(vsal);
CLOSE C1;
END;
/

=> WAP to print top 5 max salaries ?


DECLARE
CURSOR C1 IS SELECT sal FROM emp ORDER BY sal DESC;
vsal emp.sal%TYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO vsal;
EXIT WHEN C1%ROWCOUNT>5;
DBMS_OUTPUT.PUT_LINE(vsal);
END LOOP;
CLOSE C1;
END;
/

=> WAP to find min sal ?

DECLARE
CURSOR C1 IS SELECT sal FROM emp ;
m NUMBER ;
vsal emp.sal%TYPE;
BEGIN
OPEN C1;
FETCH C1 INTO m;
WHILE(C1%FOUND)
LOOP
FETCH C1 INTO vsal;
IF vsal < m THEN
m := vsal;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(m);
END;
/

20-SEP-24

=> wap to print employee names as follows ?

SMITH,ALLEN,WARD,JONES,---------------------

DECLARE
CURSOR C1 IS SELECT ename FROM emp ;
s VARCHAR2(500);
BEGIN
FOR r IN C1
LOOP
s := s||r.ename||',';
END LOOP;
DBMS_OUTPUT.PUT_LINE(s);
END;
/

LISTAGG() :-
---------------

=> built-in function used to concatenate column values.

LISTAGG(colname,seperator) WITHIN GROUP (ORDER BY COL ASC/DESC)


SELECT LISTAGG(ename,',') WITHIN GROUP (ORDER BY HIREDATE ASC) AS NAMES
FROM EMP ;

=> display employee names dept wise ?

SELECT DEPTNO,
LISTAGG(ename,',') WITHIN GROUP (ORDER BY sal DESC) AS NAMES
FROM emp
GROUP BY deptno ;

=> WAP to calculate all the students total,avg,result and insert into result
table ?

STUDENT
SNO SNAME S1 S2 S3
1 A 80 90 70
2 B 30 60 50

RESULT
SNO TOTAL AVG RESULT

DECLARE
CURSOR C1 IS SELECT sno,s1,s2,s3 FROM student ;
r result%ROWTYPE;
BEGIN
FOR s IN C1
LOOP
r.total := s.s1+s.s2+s.s3;
r.avg := r.total/3;
IF s.s1>=35 AND s.s2>=35 AND s.s3>=35 THEN
r.result := 'PASS';
ELSE
r.result := 'FAIL';
END IF;
INSERT INTO result VALUES(s.sno,r.total,r.avg,r.result);
END LOOP;
COMMIT;
END;
/

=> WAP to increment employee salaries based on the pct in emp_hike table ?

EMP_HIKE
EMPNO PCT
7369 10
7499 15
7521 12
7566 20
7654 15

=> WAP to copy data from custs to custt ?

CUSTS CUSTT
CID CNAME CID FNAME MNAME LNAME
10 SACHIN RAMESH TENDULKAR
11 MAHENDRA SINGH DHONI

REFCURSOR / DYNAMIC CURSOR :-


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

=> a cursor acts like a constant but refcursor acts like a variable.

=> select stmt declared with cursor cannot be changed during program
execution but select stmt declared with ref cursor can be changed
during program execution.

=> a cursor is called static but ref cursor is called dynamic.

Declaring REF CURSOR :-


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

C1 SYS_REFCURSOR;

Assigning Data to cursor :-


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

OPEN C1 FOR SELECT ename,sal FROM emp ;

---------

CLOSE C1;

OPEN C1 FOR SELECT deptno,dname FROM dept;

------

CLOSE C1;

Ex :-

DECLARE
C1 SYS_REFCURSOR;
e emp%ROWTYPE;
d dept%ROWTYPE;
BEGIN
OPEN C1 FOR SELECT * FROM emp ;
LOOP
FETCH C1 INTO e;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(e.ename||' '||e.sal);
END LOOP;
CLOSE C1;
OPEN C1 FOR SELECT * FROM dept;
LOOP
FETCH C1 INTO d;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(d.deptno||' '||d.dname);
END LOOP;
CLOSE C1;
END;
/

difference between cursor & ref cursor ?

CURSOR REF CURSOR

1 acts like a constant acts like a variable


2 select stmt cannot be select stmt can be
changed during program changed during program
execution execution

3 static dynamic

4 select stmt assigned to select stmt assigned at the


the cursor at the time of time of opening
declaration

5 cannot be used as can be uses as proc/func parameter


proc / func parameter

Implicit cursor :-
==================

=> cursors declared by oracle are called implicit cursor.


=> oracle declares this cursor immediately after execution of dml.
=> used to process output of dml command.
=> name of the implicit cursor is SQL.

DECLARE
veno NUMBER(4);
BEGIN
veno := &empno;
DELETE FROM emp WHERE empno = veno;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('record deleted successfully');
ELSE
DBMS_OUTPUT.PUT_LINE('employee does not exists');
END IF;
END;
/

COLLECTIONS :-
--------------

=> a collection allows group of elements of same datatype and the elements are
accessed
by using index value.

=> PL/SQL supports 3 types of collections

1 PL/SQL table OR INDEX BY table OR ASSOCIATIVE ARRAY


2 VARRAY (VARYING ARRAY)
3 NESTED TABLE

PL/SQL TABLE OR ASSOCIATIVE ARRAY :-


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

=> to use collection

1 declare collection type


2 declare variable

Declaring collection type :-


----------------------------
TYPE <name> IS TABLE OF <DATATYPE> INDEX BY <DATATYPE>;

Ex 1 :-

TYPE num_array IS TABLE OF NUMBER(4) INDEX BY BINARY_INTEGER;

X num_array ;

X(1) := 10;
X(2) := 20;

X(10) := 100;

Ex 2 :-

TYPE string_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;

S string_array ;

S(1) := 'ABC';
S(2) := 'XYZ';
S(3) := 'KLM'

=> wap to print numbers using collection ?

DECLARE
TYPE num_array IS TABLE OF NUMBER(3) INDEX BY BINARY_INTEGER;
X num_array;
BEGIN
FOR i IN 1..10
LOOP
X(i) := i*10;
END LOOP;
FOR i IN 1..10
LOOP
DBMS_OUTPUT.PUT_LINE(X(i));
END LOOP;
END;
/

X(1) = 10
X(2) = 20
X(3) = 30

X(10) = 100

=> WAP to print dept names using collection ?

DECLARE
TYPE dname_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;
d dname_array;
BEGIN
FOR i IN 1..4
LOOP
SELECT dname INTO d(i) FROM dept WHERE deptno = i*10;
END LOOP;
FOR i IN 1..4
LOOP
DBMS_OUTPUT.PUT_LINE(d(i));
END LOOP;
END;
/

d(1) = accounting
d(2) = research
d(3) = sales
d(4) = opeations

NOTE :-

=> In the above example

1 where deptno = i*10 this logic will work for dept table but not for other
tables.

2 select stmt is inside a loop , so no requests going to oracle increases


then performance degrades.

To overcome this problem use BULK COLLECT.

BULK COLLECT :-
---------------

=> using BULK COLLECT we can fetch all the required data from table
and assign that data to collection.

=> BULK COLLECT reduces no of trips to db server and improves performance.

DECLARE
TYPE dname_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;
d dname_array;
BEGIN
SELECT dname BULK COLLECT INTO d FROM dept ;
FOR i IN 1..4
LOOP
DBMS_OUTPUT.PUT_LINE(d(i));
END LOOP;
END;
/

DECLARE
TYPE ename_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;
e ename_array;
BEGIN
SELECT ename BULK COLLECT INTO e FROM emp ;
FOR i IN 1..12
LOOP
DBMS_OUTPUT.PUT_LINE(e(i));
END LOOP;
END;
/

collection methods :-
---------------------

first :- returns index value of the first element


last :- returns index value of the last element
next :- returns index value of the next element
prior :- returns index value of the previous element
count :- returns total no of elements in collection
exists :- to check whether element exists in the collection or not
extend :- to increase the size of the collection

collectionname.method

DECLARE
TYPE ename_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;
e ename_array;
BEGIN
SELECT ename BULK COLLECT INTO e FROM emp ;
FOR i IN e.first..e.last
LOOP
DBMS_OUTPUT.PUT_LINE(e(i));
END LOOP;
END;
/

=> difference between cursor and collection ?

CURSOR COLLECTION

1 fetching is row-by-row all rows fetched at a time and assigned


to collection.

2 gives poor performance gives good performance.

3 program consumes less memory program consumes more memory

4 supports only forward navigation supports both forward and


backward navigation

5 doesn't support random accessing supports random accessing

backward navigation :-
----------------------

DECLARE
TYPE ename_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;
e ename_array;
BEGIN
SELECT ename BULK COLLECT INTO e FROM emp ;
FOR i IN REVERSE e.first..e.last
LOOP
DBMS_OUTPUT.PUT_LINE(e(i));
END LOOP;
END;
/

forward navigation using while loop :-


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

DECLARE
TYPE ename_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER ;
e ename_array;
x NUMBER ;
BEGIN
SELECT ename BULK COLLECT INTO e FROM emp ;
x := e.first;
WHILE(x<=e.last)
LOOP
DBMS_OUTPUT.PUT_LINE(e(x));
x := e.next(x);
END LOOP;
END;
/

backward navigation using while loop :-


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

Bulk collecting records :-


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

DECLARE
TYPE emp_array IS TABLE OF EMP%ROWTYPE INDEX BY BINARY_INTEGER;
e emp_array;
BEGIN
SELECT * BULK COLLECT INTO e FROM emp ;
FOR i IN e.first..e.last
LOOP
DBMS_OUTPUT.PUT_LINE(e(i).ename||' '||e(i).sal);
END LOOP;
END;
/

e
1 7369 SMITH CLERK - 17-DEC-80 800 NULL 20
2

14

VARRAY ;-
---------

DECLARE
TYPE num_array IS VARRAY(5) OF NUMBER(3);
e num_array := num_array();
BEGIN
FOR i IN 1..5
LOOP
e.extend;
e(i) := i*10;
END LOOP;
FOR i IN 1..5
LOOP
DBMS_OUTPUT.PUT_LINE(e(i));
END LOOP;
END;
/

NESTED TABLE :-
-------------
DECLARE
TYPE num_array IS TABLE OF NUMBER(3);
e num_array := num_array();
BEGIN
FOR i IN 1..5
LOOP
e.extend;
e(i) := i*10;
END LOOP;
FOR i IN 1..5
LOOP
DBMS_OUTPUT.PUT_LINE(e(i));
END LOOP;
END;
/

pl/sql table varray nested table

1 not declared declared not declared with


with size with size size

2 index can be index must index must be


number/varchar2 be always always integer
integer

4 initialization initialization intialization is required


is not required required

5 array size grows array size array size grows


automatically grows by calling by calling extend method
extend method

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

25-sep-24

ERROR HANDLING / EXCEPTION HANDLING :-


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

1 syntax errors
2 logical errors
3 runtime errors (exception)

=> errors that are raised during program execution are called runtime errors.

ex :- x number(3);

x := &x; => 1000 => runtime error

=> if any statement causes runtime error then program execution is terminated
and oracle displays error message, To continue the program execution
and to replace system generated message with our own simple and user
friendly message then we need to handle that runtime error.

=> To handle runtime errors then we need to include a block called EXCEPTION block

DECLARE
declaration-part;
BEGIN
statements; => causes exception
EXCEPTION
statements; => handles exception
END;
/

=> exceptions are 2 types

1 system defined
2 user defined

system defined :-
------------------

=> errors raised by oracle are called system defined errors

1 ZERO_DIVIDE => raised when we try to divide number with 0


2 VALUE_ERROR => raised when variable type or size mismatches
3 INVALID_NUMBER => raised when invalid calculation is performed
4 NO_DATA_FOUND => raised when data not found in the table
5 TOO_MANY_ROWS => raised when select stmt fetches more than one row
6 DUP_VAL_ON_INDEX => raised when we try to insert duplicate value into primary
key column

EXCEPTION
WHEN EX1 THEN
statements;
WHEN EX2 THEN
statements;
-------
WHEN OTHERS THEN
statements;
END;
/

Example 1 :-

DECLARE
a NUMBER(3);
b NUMBER(3);
c NUMBER(3);
BEGIN
a := &a;
b := &b;
c := a/b;
DBMS_OUTPUT.PUT_LINE(c);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('divisor cannot be zero');
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('value exceeding size');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('unknown error');
END;
/

=> write a prog to input empno and print name & salary ?
DECLARE
veno emp.empno%TYPE;
vename emp.ename%TYPE;
vsal emp.sal%TYPE;
BEGIN
veno := &empno;
SELECT ename,sal INTO vename,vsal FROM emp WHERE empno = veno ;
DBMS_OUTPUT.PUT_LINE(vename||' '||vsal);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('invalid empno');
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE(' value exceeding size');
END;
/

SQLCODE & SQLERRM :-


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

=> system variables useful for error handling

SQLCODE => returns error code


SQLERRM => returns error message

Example :-

CREATE TABLE EMP44


(
EMPNO NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10),
SAL NUMBER(7) CHECK(SAL>=3000)
);

wap to insert data into emp44 table ?

DECLARE
veno emp44.empno%TYPE;
vename emp44.ename%TYPE;
vsal emp44.sal%TYPE;
BEGIN
veno := &empno;
vename := '&ename';
vsal := &sal;
INSERT INTO emp44 VALUES(veno,vename,vsal);
COMMIT;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('empno should not be duplicate');
WHEN OTHERS THEN
IF SQLCODE = -02290 THEN
DBMS_OUTPUT.PUT_LINE(' sal must be min 3000');
ELSE
DBMS_OUTPUT.PUT_LINE('unknown error');
END IF;
END;
/

26-SEP-24
USER DEFINED ERRORS :-
-----------------------

=> errors raised by user are called user defined errors


=> user raises exception to stop program execution based on some condition.
=> the following built-in is used to raise exception

RAISE_APPLICATION_ERROR(error code,error msg);

error code => -20001 to -20999

Example 1 :-

=> WAP to increment specific employee sal by specific amount but sunday updates
are not
allowed ?

DECLARE
veno emp.empno%TYPE;
vamt NUMBER(5);
BEGIN
veno := &empno;
vamt := &amount;
IF TO_CHAR(SYSDATE,'DY')='SUN' THEN
RAISE_APPLICATION_ERROR(-20001,'sunday not allowed');
END IF;
UPDATE emp SET sal = sal + vamt WHERE empno = veno ;
COMMIT;
END;
/

=> write a prog to process money transfer ?

ACCOUNTS
ACCNO ACTYPE BAL
100 S 10000
101 C 20000

TRANSACTIONS
TRID TTYPE TDATE TAMT ACCNO

CREATE SEQUENCE S1
START WITH 1
INCREMENT BY 1
MAXVALUE 9999;

DECLARE
vsacno accounts.accno%TYPE;
vtacno accounts.accno%TYPE;
vamt NUMBER(5);
vbal accounts.bal%TYPE;
cnt NUMBER(2);
BEGIN
vsacno := &sacno;
vtacno := &tacno;
vamt := &amount;
SELECT bal INTO vbal FROM accounts WHERE accno = vsacno ;
SELECT COUNT(*) INTO cnt FROM accounts WHERE accno = vtacno;
IF cnt=0 THEN
RAISE_APPLICATION_ERROR(-20001,'target account does not exists');
END IF;
IF vamt > vbal THEN
RAISE_APPLICATION_ERROR(-20002,'insufficient balance');
END IF;
UPDATE accounts SET bal = bal - vamt WHERE accno = vsacno;
UPDATE accounts SET bal = bal + vamt WHERE accno = vtacno;
INSERT INTO transactions VALUES(S1.NEXTVAL,'W',SYSDATE,vamt,vsacno);
INSERT INTO transactions VALUES(S1.NEXTVAL,'D',SYSDATE,vamt,vtacno);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20001,'source account does not exist');
END;
/

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

NAMED PL/SQL Blocks :-


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

1 PROCEDURES
2 FUNCTIONS
3 PACKAGES
4 TRIGGERS

SUB-PROGRAMS :-
----------------

1 PROCEDURES
2 FUNCTIONS
3 PACKAGES

Advantages :-
-------------

1 modular programming :-
------------------------

=> with the help of procedures and function we can divide a big pl/sql program
into
small modules.

2 reusability :-
-------------

=> procedures and functions can be stored in db and applications which are
connected to
db can reuse procedures & functions.

3 invoked from front-end :-


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

=> proc & func can be called from front-end applications like java /.net / python
4 improves performance :-
----------------------

=> proc & func improves performance because they are precompiled i.e. compiled
already
and ready for execution , if we create a procedure program is compiled and
stored in db and whenever we call procedure only execution is repeated but
not
compilation , so this improves performance.

27-sep-24

PROCEDURES :-
---------------

=> a procedure is a named PL/SQL Block that accepts some input performs some
action on db
and may or may not returns a value.

=> procedures are created to perform one or more dml operations on tables.

CREATE OR REPLACE PROCEDURE <NAME>


(
parameters if any
)
IS
declaration-part;
BEGIN
statements;
END;
/

parameters :-
-------------

=> we can declare parameters and we can pass values to parameters


=> parameters are 3 types

1 IN (default)
2 OUT
3 IN OUT

=> IN parameter always receives value


=> OUT parameter always sends value
=> IN OUT receives and sends

MAIN PROCEDURE

X ====================> A (IN)

Y <=================== B (OUT)

Z ===================> C (IN OUT)


<====================

Example 1 :- without parameters

=> create procedure to increment all the employee salaries by 1000 ?


CREATE OR REPLACE PROCEDURE raise_salary
IS
BEGIN
UPDATE emp SET sal = sal + 1000;
COMMIT;
END;
/

procedure created (compiled + stored in db)

Execution :-
------------

1 sql prompt
2 another pl/sql prog
3 front end applications

Executing from sql prompt :-


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

SQL>EXECUTE procname ;

Ex :- SQL>EXECUTE raise_salary ;

Example 2 :- with parameters

=> create procedure to increment to specific employee sal by specific amount ?

CREATE OR REPLACE PROCEDURE raise_salary


(
peno IN emp.empno%TYPE ,
pamt IN NUMBER
)
IS
BEGIN
UPDATE emp SET sal = sal + pamt WHERE empno = peno ;
COMMIT;
END;
/

Execution :-
-----------

SQL>EXECUTE raise_salary(7369,1000); positional association

SQL>EXECUTE raise_salary(peno=>7369,pamt=>1000); named association

SQL>EXECUTE raise_salary(pamt=>1000,peno=>7369);

Example 3 :- OUT parameter

=> create procedure to increment specific employee sal by specific amount


after increment send the updated sal to calling program ?

CREATE OR REPLACE PROCEDURE raise_salary


(
peno IN emp.empno%TYPE,
pamt IN NUMBER,
pnewsal OUT emp.sal%TYPE
)
IS
BEGIN
UPDATE emp SET sal = sal + pamt WHERE empno = peno ;
COMMIT;
SELECT sal INTO pnewsal FROM emp WHERE empno = peno;
END;
/

Execution :-

SQL>VARIABLE K NUMBER ;

SQL>EXECUTE raise_salary(7369,1000,:K);

SQL> PRINT :K

NOTE :- variables declared at sql prompt are called bind variables and variables
are prefixed with : operator.

Example 4 :- parameters with default values

=> a parameter can be declared with default value as follows

pamt IN NUMBER DEFAULT 500

=> while calling procedure if we don't pass value to pamt then oracle assigns
default value

CREATE OR REPLACE PROCEDURE raise_salary


(
peno IN emp.empno%TYPE,
pamt IN NUMBER DEFAULT 500,
pnewsal OUT emp.sal%TYPE
)
IS
BEGIN
UPDATE emp SET sal = sal + pamt WHERE empno = peno ;
COMMIT;
SELECT sal INTO pnewsal FROM emp WHERE empno = peno;
END;
/

Execution :-

SQL>EXECUTE raise_salary(peno=>7369,pnewsal=>:K);

SQL>PRINT :K

28-sep-24

=> create a procedure to copy data from custs to custt ?

CUSTS CUSTT
CID CNAME CID FNAME MNAME LNAME
10 SACHIN RAMESH TENDULKAR
11 MAHENDRA SINGH DHONI

CREATE OR REPLACE PROCEDURE COPY_CUSTS_CUSTT


IS
CURSOR C1 IS SELECT cid,cname
FROM custs
WHERE cid NOT IN (SELECT cid FROM custt) ;
f VARCHAR2(20);
m VARCHAR2(20);
l VARCHAR2(20);
BEGIN
FOR r IN C1
LOOP
f := REGEXP_SUBSTR(r.cname,'[A-Z]+',1,1);
m := REGEXP_SUBSTR(r.cname,'[A-Z]+',1,2);
l := REGEXP_SUBSTR(r.cname,'[A-Z]+',1,3);
INSERT INTO custt VALUES(r.cid,f,m,l);
END LOOP;
COMMIT;
END;
/

USER DEFINED FUNCTIONS :-


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

=> functions created by user are called user defined functions.

=> when predefine functions not meeting our requirements then we create our own
function called user defined function.

=> a function is also a named PL/SQL block that accepts some input performs
some calculation and must return a value.

=> functions are created

1 for calculations
2 to fetch value from db

CREATE OR REPLACE
FUNCTION <NAME>(parameters) RETURN <type>
IS
declaration-part;
BEGIN
statements;
RETURN expr;
END;
/

Ex 1 :-

CREATE OR REPLACE
FUNCTION CALC(a NUMBER,b NUMBER,op CHAR) RETURN NUMBER
IS
BEGIN
IF op='+' THEN
RETURN(a+b);
ELSIF op='-' THEN
RETURN(a-b);
ELSIF op='*' THEN
RETURN(a*b);
ELSE
RETURN(a/b);
END IF;
END;
/

function created (compiled + stored in db)

Execution :-

1 SQL commands
2 another pl/sql prog
3 front-end

from sql commands :-


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

SQL>SELECT CALC(10,20,'*') FROM DUAL ; => 200

=> create a function to check whether given year is leap or not ?

CREATE OR REPLACE
FUNCTION IS_LEAP(y NUMBER) RETURN VARCHAR2
IS
d DATE;
BEGIN
d := '29-FEB-'||y ;
RETURN 'leap year';
EXCEPTION
WHEN OTHERS THEN
RETURN 'not a leap year';
END;
/

Execution :-

SQL>SELECT IS_LEAP(2024) FROM DUAL ; => leap year

SQL>SELECT IS_LEAP(2023) FROM DUAL ; => not a leap year

=> list of employees joined in leap year ?

SELECT *
FROM emp
WHERE IS_LEAP(TO_CHAR(hiredate,'YYYY')) = 'leap year' ;

SQL>SELECT ENAME,IS_LEAP(TO_CHAR(HIREDATE,'YYYY')) AS LEAP FROM EMP ;

function returning records :-


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

=> create a function that accepts deptno and returns list of employees working
for that dept ?

CREATE OR REPLACE
FUNCTION getEmpList(pdno NUMBER) RETURN SYS_REFCURSOR
IS
C1 SYS_REFCURSOR;
BEGIN
OPEN C1 FOR SELECT * FROM EMP WHERE DEPTNO = pdno ;
RETURN C1;
END;
/

Execution :-

SQL> SELECT getEmpList(30) FROM DUAL ;

30-SEP-24

=> create a function to return top N employees based on sal ?

CREATE OR REPLACE
FUNCTION getTopNEmpList(n NUMBER) RETURN SYS_REFCURSOR
IS
C1 SYS_REFCURSOR;
BEGIN
OPEN C1 FOR SELECT *
FROM (SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ) E
WHERE RNK<= n ;
RETURN C1;
END;
/

Execution :-

SQL>SELECT getTopNEmpList(3) FROM DUAL ;

=> a function can have multiple return statements ?

ans :- yes but always one return statement is executed.

=> is function can be created with out parameter ?

ans :- yes but not recommended

=> is procedure can have return statement ?

ans :- yes , but return stmt in procedure cannot return value

=> In functions dmls statements are allowed ?

ans :- yes but not recommended.

=> difference between procedures & functions ?

procedures functions

1 may or may not returns a value must return a value


2 can return multiple values always returns one value
3 returns values using out parameter returns value using return stmt
4 cannot be called from sql commands can be called from sql commands
5 created to perform dml created for calculations or
to fetch data from table
6 create procedure to update balance create function to get balance

USER_SOURCE :-
==============

=> system table that stores procedures & functions created by user

NAME TYPE LINE TEXT


IS_LEAP FUNC 1 FUNCTION IS_LEAP(y NUMBER) RETURN VARCHAR2
2 IS
3 d DATE;
4 BEGIN

list of procedures & functions created ?

SELECT DISTINCT NAME,TYPE FROM USER_SOURCE ;

SELECT TEXT FROM USER_SOURCE WHERE NAME='IS_LEAP' ;

Droping :-
----------

SQL>DROP PROCEDURE RAISE_SALARY ;


SQL>DROP FUNCTION IS_LEAP ;

PACKAGES :-
-----------

=> a package is a collection of procedures & functions.


=> related procedures & functions can be grouped into one package.

Advantages :-
---------------

1 easy to manage :-
---------------

=> because related procedures & functions available in single package , so


managing is easy.

2 supports overloading :-
-----------------------

=> standalone proc & func cannot be overloaded but In package we can
define two or more proc & func with same name with different parameters.

3 supports hiding :-
------------------

=> In package we can declare proc & func as public and private, public
members can be called from any where but private members can be
called with in package.

4 improves performance :-
-----------------------

=> when application prog requests for a proc/func in a package then


oracle not only loads requested member but entire package loaded
into memory and next request will not go to db and no of requests
going to db are reduced and performance is improved.

=> package consists of two parts

1 package specification
2 package body

package specification :-
-----------------------

=> package specification contains declarations of procedures & functions.

CREATE OR REPLACE PACKAGE <name>


AS
PROCEDURE DECLARATION ;
FUNCTION DECLARATION;
--------------- ;
END;
/

package body :-
----------------

=> package body contains procedures & functions defintion.

CREATE OR REPLACE PACKAGE BODY <NAME>


AS
PROCEDURE <NAME>(parameters)
IS
BEGIN
---------- ;
END <NAME>;
FUNCTION <NAME>(parameters) RETURN type
IS
BEGIN
statements;
RETURN expr;
END <name>;
-----

END;
/

1-OCT-24

=> create package to implement various bank transactions ?

ACCOUNTS
ACCNO ACTYPE BAL

TRANSACTIONS
TRID TTYPE TDATE TAMT ACCNO
CREATE SEQUENCE S10
START WITH 1
INCREMENT BY 1
MAXVALUE 9999 ;

1 account opening (proc)


2 accoung closing (proc)
3 balance enquiry (func)
4 money deposit (proc)
5 money withdrawl (proc)
6 money transfer (proc)
7 statement between two given dates (func)
8 latest N transactions (func)

specification :-
---------------

CREATE OR REPLACE PACKAGE BANK


AS
PROCEDURE new_acct(a NUMBER,t CHAR,b NUMBER);
PROCEDURE close_acct(a NUMBER);
FUNCTION getBal(a NUMBER) RETURN NUMBER;
PROCEDURE credit(a NUMBER,amt NUMBER);
PROCEDURE debit(a NUMBER,amt NUMBER);
PROCEDURE transfer(s NUMBER,t NUMBER,amt NUMBER);
FUNCTION getStmt(a NUMBER,s DATE,e DATE) RETURN SYS_REFCURSOR;
FUNCTION getStmt(a NUMBER,n NUMBER) RETURN SYS_REFCURSOR;
END;
/

package body :-
---------------

CREATE OR REPLACE PACKAGE BODY BANK


AS
PROCEDURE new_acct(a NUMBER,t CHAR,b NUMBER)
IS
BEGIN
INSERT INTO accounts VALUES(a,t,b);
COMMIT;
END new_acct;
PROCEDURE close_acct(a NUMBER)
IS
BEGIN
DELETE FROM accounts WHERE accno = a;
COMMIT;
END close_acct;
FUNCTION getBal(a NUMBER) RETURN NUMBER
IS
vbal accounts.bal%TYPE;
BEGIN
SELECT bal INTO vbal FROM accounts WHERE accno = a ;
RETURN vbal;
END getBal ;
PROCEDURE credit(a NUMBER,amt NUMBER)
IS
BEGIN
UPDATE accounts SET bal = bal + amt WHERE accno = a;
INSERT INTO transactions VALUES(s10.NEXTVAL,'D',SYSDATE,amt,a);
COMMIT;
END credit;
PROCEDURE debit(a NUMBER,amt NUMBER)
IS
vbal accounts.bal%TYPE;
BEGIN
vbal := getBal(a) ;
IF amt > vbal THEN
RAISE_APPLICATION_ERROR(-20001,'insufficient balance');
END IF;
UPDATE accounts SET bal = bal - amt WHERE accno = a;
INSERT INTO transactions VALUES(s10.NEXTVAL,'W',SYSDATE,amt,a);
COMMIT;
END debit;
PROCEDURE transfer(s NUMBER,t NUMBER,amt NUMBER)
IS
BEGIN
debit(s,amt);
credit(t,amt);
END transfer;
FUNCTION getStmt(a NUMBER,s DATE,e DATE) RETURN SYS_REFCURSOR
IS
C1 SYS_REFCURSOR;
BEGIN
OPEN C1 FOR SELECT *
FROM transactions
WHERE accno = a
AND
tdate BETWEEN s AND e ;
RETURN C1;
END getStmt;
FUNCTION getStmt(a NUMBER,n NUMBER) RETURN SYS_REFCURSOR
IS
C1 SYS_REFCURSOR;
BEGIN
OPEN C1 FOR SELECT *
FROM transactions
WHERE accno = a
ORDER BY tdate DESC
FETCH FIRST n ROWS ONLY ;
RETURN C1;
END getStmt;
END;
/

Execution :-
============

packagename.member(parameters)

Ex :-

SQL>EXECUTE BANK.new_acct(100,'S',10000);
SQL>EXECUTE BANK.credit(100,5000);
SQL>EXECUTE BANK.debit(100,2000);
SQL>SELECT BANK.GETSTMT(100,3) FROM DUAL ;
Droping :-
----------

SQL>DROP PACKAGE BANK ; => drops package specification & body

SQL>DROP PACKAGE BODY BANK ; => drops only body but not specification

=> create a package to implement various operations on emp table ?

1 hire employee (proc)


2 fire employee (proc)
3 update salary (proc)
4 calculate experience (func)
5 return top n employees based on sal (func)

2-OCT-24

TRIGGERS :-
-----------

=> a trigger is also a named PL/SQL block like procedure but executed implicitly
by oracle whenever user submits DML/DDL commands.

=> triggers are created

1 to control dmls/ddls
2 to enforce complex rules and validations
3 to audit day-to-day operations on tables

CREATE OR REPLACE TRIGGER <NAME>


BEFORE / AFTER INSERT OR UPDATE OR DELETE
ON <TABNAME>
[FOR EACH ROW]
[
DECLARE
variables
]
BEGIN
statements;
END;
/

BEFORE triggers :-
------------------

=> if trigger is before then oracle executes the trigger before executing dml

1 TRIGGER
2 DML

AFTER trigger :-
----------------

=> if trigger is after then oracle executes the trigger after executing dml

1 DML
2 TRIGGER

TRIGGER levels :-
------------------

1 statement level (default)


2 row level

=> statement level triggers are executed once per the dml.
=> row level triggers are executed once per the row affected by dml.

Examples :-

=> create trigger to not to allow dmls on emp table on sunday ?

CREATE OR REPLACE TRIGGER T1


BEFORE INSERT OR UPDATE OR DELETE
ON EMP
BEGIN
IF TO_CHAR(SYSDATE,'DY') ='SUN' THEN
RAISE_APPLICATION_ERROR(-20001,'sunday not allowed');
END IF;
END;
/

Testing :-

SQL>UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = 7566 ; => ERROR

=> create trigger to not to allow dmls on emp table as follows ?

mon - fri <10am and >4pm


sat <10am and >2pm
sun ------------

CREATE OR REPLACE TRIGGER T2


BEFORE INSERT OR UPDATE OR DELETE
ON EMP
BEGIN
IF TO_CHAR(SYSDATE,'D') BETWEEN 2 AND 6 THEN
IF TO_CHAR(SYSDATE,'HH24') < 10 OR TO_CHAR(SYSDATE,'HH24') >= 16 THEN
RAISE_APPLICATION_ERROR(-20001,'only between 10am and 4pm');
END IF;
ELSIF TO_CHAR(SYSDATE,'DY')='SAT' THEN
IF TO_CHAR(SYSDATE,'HH24') < 10 OR TO_CHAR(SYSDATE,'HH24') >= 14 THEN
RAISE_APPLICATION_ERROR(-20001,'only between 10am and 2pm');
END IF;
ELSE
RAISE_APPLICATION_ERROR(-20001,'sunday not allowed');
END IF;
END;
/

Testing :-
----------

SQL>DELETE FROM emp WHERE empno = 7844; => error

=> create trigger to not to allow to update empno ?

CREATE OR REPLACE TRIGGER T3


BEFORE UPDATE OF EMPNO
ON EMP
BEGIN
RAISE_APPLICATION_ERROR(-20001,'cannot update empno');
END;
/

Testing :-

SQL>UPDATE EMP SET EMPNO = 9999 WHERE EMPNO = 7844 ; => ERROR

3-oct-24

:NEW & :OLD variables :-


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

=> these variables are called bind variables and rowtype variables.
=> using these two variables we can access data in triggers affected by dml.
=> record user is trying to insert is copied to :NEW variable.
=> record user is trying to delete is copied to :OLD variable.
=> record user is trying to update is copied to both :OLD & :NEW variable.

INSERT INTO EMP VALUES(100,'A','CLERK',4000,-------) ; => :NEW

UPDATE EMP SET SAL=5000 WHERE EMPNO = 100 ; => => :NEW
EMPNO SAL
100 5000

:OLD
EMPNO SAL
100 4000

DELETE FROM EMP WHERE EMPNO = 100 ; => :OLD

=> these two variables are allowed only in row level trigger but not allowed in
stmt level triggers

Ex :-

=> create trigger to not to allow to decrement salary ?

CREATE OR REPLACE TRIGGER T4


BEFORE UPDATE
ON EMP
FOR EACH ROW
BEGIN
IF :NEW.SAL < :OLD.SAL THEN
RAISE_APPLICATION_ERROR(-20001,'sal cannot be decremented');
END IF;
END;
/

Testing :-
-----------

SQL>UPDATE EMP SET SAL=1000 WHERE EMPNO = 7369 ; => :OLD :NEW
SAL SAL
4300 1000
1 ROW IS COPIED TO :OLD & :NEW
2 EXECUTES TRIGGER
3 EXECUTES DML

=> create trigger to insert details into emp_resign when employee resigns ?

EMP_RESIGN
EMPNO ENAME JOB SAL HIREDATE DOR

CREATE TABLE EMP_RESIGN


(
EMPNO NUMBER(4),
ENAME VARCHAR2(10),
JOB VARCHAR2(10),
SAL NUMBER(7,2),
HIREDATE DATE,
DOR DATE
);

CREATE OR REPLACE TRIGGER T5


AFTER DELETE
ON EMP
FOR EACH ROW
BEGIN
INSERT INTO EMP_RESIGN
VALUES(:OLD.EMPNO,:OLD.ENAME,:OLD.JOB,:OLD.SAL,:OLD.HIREDATE,SYSDATE);
END;
/

Testing :-
----------

SQL>DELETE FROM EMP WHERE EMPNO = 7369 ; => :OLD

1 row is copied to :old


2 dml
3 trigger

SQL>DELETE FROM EMP WHERE EMPNO IN (7499,7521);

1 7499 => :OLD => DELETED => TRIGGER


2 7521 => :OLD => DELETED => TRIGGER

=> create trigger to replicate changes made to custs to custt ?

CUSTS CUSTT
CID NAME ADDR CID NAME ADDR

CREATE TABLE CUSTS


(
CID NUMBER(2),
NAME VARCHAR2(10),
ADDR VARCHAR2(10)
);
CREATE TABLE CUSTT
AS
SELECT * FROM CUSTS ;

CREATE OR REPLACE TRIGGER T6


AFTER INSERT OR UPDATE OR DELETE
ON CUSTS
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO CUSTT VALUES(:NEW.CID,:NEW.NAME,:NEW.ADDR);
ELSIF UPDATING THEN
UPDATE CUSTT SET ADDR = :NEW.ADDR WHERE CID = :NEW.CID ;
ELSE
DELETE FROM CUSTT WHERE CID = :OLD.CID;
END IF;
END;
/

Testing :-
----------

SQL>INSERT INTO CUSTS VALUES(10,'A','HYD'); => :NEW


SQL>UPDATE CUSTS SET ADDR='MUM' WHERE CID=10 ; => :NEW :OLD
SQL>DELETE FROM CUSTS WHERE CID=10 ; => :OLD

How many triggers can be created on table ?

ANS :- 12
I
R
B
U
S
A
D

what is the order of execution of triggers ?

BEFORE STMT
BEFORE ROW
AFTER ROW
AFTER STMT

Compound trigger :-
--------------------

=> using compound trigger we can define multiple triggers in one trigger

create or replace trigger T10


for UPDATE
on emp
compound trigger

before statement is
begin
DBMS_OUTPUT.PUT_LINE('before stmt');
end before statement;
before each row is
begin
DBMS_OUTPUT.PUT_LINE('before row');
end before each row;

after each row is


begin
DBMS_OUTPUT.PUT_LINE('after row');
end after each row;

after statement is
begin
DBMS_OUTPUT.PUT_LINE('after stmt');
end after statement;
end;

update emp set sal=2000 where empno IN (7788,7902);

BEFORE STMT
BEFORE ROW
AFTER ROW
BEFORE ROW
AFTER ROW
AFTER STMT

USER_TRIGGERS :-
----------------

=> stores triggers created by user

SELECT TRIGGER_NAME,
TRIGGER_TYPE,
TRIGGERING_EVENT
FROM USER_TRIGGERS
WHERE TABLE_NAME='EMP' ;

Droping :-
----------

SQL>DROP TRIGGER T1 ;

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

4-oct-24

Dynamic SQL :-
==============

=> SQL commands generated at runtime are called dynamic sql commands.

ex :- DROP TABLE EMP ; (static sql command)

tname VARCHAR2(20);
tname := '&tabname';

DROP TABLE tname ; (dynamic sql command)

=> Dynamic SQL is useful when we don't know table names


and column names until runtime.

=> To execute DDL/Dynamic SQL commands use EXECUTE IMMEDIATE.

EXECUTE IMMEDIATE ' DYNAMI SQL COMMAND / DDL COMMAND '

=> Dynamic SQL / DDL command that you want to execute shuold be passed as a
string to EXECUTE IMMEDIATE.

Ex 1 :-

create a procedure to drop table ?

CREATE OR REPLACE PROCEDURE DROP_TABLE


(
tname IN VARCHAR2
)
IS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE '||tname;
END;
/

Execution :-

SQL>EXECUTE DROP_TABLE('CUSTS');

Ex 2 :-

=> create procedure to drop all tables ?

CREATE OR REPLACE PROCEDURE DROP_ALL_TABLES


IS
CURSOR C1 IS SELECT TABLE_NAME FROM USER_TABLES ;
BEGIN
FOR R IN C1
LOOP
EXECUTE IMMEDIATE 'DROP TABLE '||R.TABLE_NAME||' CASCADE CONSTRAINTS ';
END LOOP;
END;
/

Execution :-

SQL>EXECUTE DROP_ALL_TABLES ;

=> wap to display no of rows in all tables ?

EMP ??
DEPT ??
CUST ??

DECLARE
CURSOR C1 IS SELECT TABLE_NAME FROM USER_TABLES ;
str VARCHAR2(1000);
cnt NUMBER;
BEGIN
FOR R IN C1
LOOP
str := 'SELECT COUNT(*) FROM '||R.TABLE_NAME;
EXECUTE IMMEDIATE str INTO cnt;
DBMS_OUTPUT.PUT_LINE(R.TABLE_NAME||' '||cnt);
END LOOP;
END;
/

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

UTL_FILE package :-
-------------------

=> system package used to work with files.

=> using this package we can create new files,write data into files and read
data from files.

members :-
----------

1 FILE_TYPE => It is a datatype


2 FOPEN => It is a function used to open file
3 PUT_LINE => It is a procedure used to write data into file
4 GET_LINE => It is a procedure used to read data from file
5 FCLOSE => It is a procedure used to close file.

Directory Object :-
------------------

=> It is an object in db that points to operating system directory


=> created by DBA and granted to users.

SYSTEM/MANAGER :-
---------------

SQL>CREATE DIRECTORY D10 AS 'C:\PLSQL' ;

SQL>GRANT READ,WRITE ON DIRECTORY D10 TO BATCH430 ;

program for creating new file :-


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

DECLARE
f1 UTL_FILE.FILE_TYPE;
BEGIN
f1 := UTL_FILE.FOPEN('D10','abc.txt','W');
UTL_FILE.PUT_LINE(f1,'HELLO');
UTL_FILE.PUT_LINE(f1,'WELCOME');
UTL_FILE.PUT_LINE(f1,'UTL_FILE PACKAGE');
UTL_FILE.FCLOSE(f1);
END;
/
program to read data from file :-
--------------------------------

DECLARE
f1 UTL_FILE.FILE_TYPE;
s VARCHAR2(1000);
BEGIN
f1 := UTL_FILE.FOPEN('D10','abc.txt','r');
LOOP
UTL_FILE.GET_LINE(f1,s);
DBMS_OUTPUT.PUT_LINE(s);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(f1);
END;
/

5-oct-24

program to copy data from table to file :-


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

DECLARE
f1 UTL_FILE.FILE_TYPE;
CURSOR C1 IS SELECT empno,ename,sal FROM emp ;
s VARCHAR2(500);
BEGIN
f1 := UTL_FILE.FOPEN('D10','emp.txt','W');
FOR r IN C1
LOOP
s := r.empno||','||r.ename||','||r.sal;
UTL_FILE.PUT_LINE(f1,s);
END LOOP;
UTL_FILE.FCLOSE(f1);
END;
/

DECLARE
f1 UTL_FILE.FILE_TYPE;
CURSOR C1 IS SELECT empno,ename,sal FROM emp ;
s VARCHAR2(500);
BEGIN
f1 := UTL_FILE.FOPEN('D10','emp.csv','W');
FOR r IN C1
LOOP
s := r.empno||','||r.ename||','||r.sal;
UTL_FILE.PUT_LINE(f1,s);
END LOOP;
UTL_FILE.FCLOSE(f1);
END;
/

program to copy data from file to table :-


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

CREATE TABLE EMP44


(
EMPNO NUMBER(4),
ENAME VARCHAR2(10),
SAL NUMBER(7)
);

DECLARE
f1 UTL_FILE.FILE_TYPE;
s VARCHAR2(1000);
veno NUMBER(4);
vename VARCHAR2(10);
vsal NUMBER(7);
BEGIN
f1 := UTL_FILE.FOPEN('D10','emp.csv','R');
LOOP
UTL_FILE.GET_LINE(f1,s);
veno := REGEXP_SUBSTR(s,'[^,]+',1,1);
vename := REGEXP_SUBSTR(s,'[^,]+',1,2);
vsal := REGEXP_SUBSTR(s,'[^,]+',1,3);
INSERT INTO emp44 VALUES(veno,vename,vsal);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(f1);
END;
/

Working with LOBs :-


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

=> oracle provided the following two types for storing multimedia objects
like audio,video,images.

1 BFILE (Binary File)


2 BLOB (Binary Large Object)

BFILE :-
----------

=> BFILE is called external lob because lob is stored outside db but db stores
path
=> to store path in db use function BFILENAME.

BFILENAME(dir obj,file name);

Ex :-

CREATE TABLE CUST


(
CID NUMBER(2),
CNAME VARCHAR2(10),
PHOTO BFILE
);

INSERT INTO CUST VALUES(10,'ABC',BFILENAME('D10','TIGER.jfif'));

BLOB :-
-------
=> BLOB is called internal lob because lob is stored inside db

Ex :-

CREATE TABLE CUST


(
CID NUMBER(2),
CNAME VARCHAR2(10),
CPHOTO BLOB
);

INSERT INTO CUST VALUES(10,'ABC',EMPTY_BLOB());

=> create a procedure to update customer photo ?

CREATE OR REPLACE PROCEDURE update_cust_photo


(
d IN NUMBER,
f IN VARCHAR2
)
IS
s BFILE;
t BLOB;
x NUMBER;
BEGIN
s := BFILENAME('D10',f);
SELECT cphoto INTO t FROM cust WHERE cid = d FOR UPDATE ;
DBMS_LOB.OPEN(s,DBMS_LOB.LOB_READONLY);
x := DBMS_LOB.GETLENGTH(s);
DBMS_LOB.LOADFROMFILE(t,s,x);
UPDATE cust SET cphoto = t WHERE cid=d;
COMMIT;
DBMS_LOB.CLOSE(s);
END;
/

Execution :-

sql>SELECT LENGTH(CPHOTO) FROM CUST WHERE CID=10;

LENGTH(CPHOTO)
--------------
0

SQL> EXECUTE UPDATE_CUST_PHOTO(10,'TIGER.JFIF');

SQL> SELECT LENGTH(CPHOTO) FROM CUST WHERE CID=10;

LENGTH(CPHOTO)
--------------
7305

BLOB TO FILE :-
----------------

CREATE OR REPLACE PROCEDURE BLOB_TO_FILE


(
d IN NUMBER,
f IN VARCHAR2
)
IS
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob BLOB;
l_blob_len INTEGER;
BEGIN
-- Get LOB locator
SELECT cphoto INTO l_blob
FROM cust
WHERE cid = d ;

l_blob_len := DBMS_LOB.getlength(l_blob);

-- Open the destination file.

l_file := UTL_FILE.fopen('D10',f,'wb', 32767);

-- Read chunks of the BLOB and write them to the file


-- until complete.
WHILE l_pos <= l_blob_len
LOOP
DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
UTL_FILE.put_raw(l_file, l_buffer, TRUE);
l_pos := l_pos + l_amount;
END LOOP;

-- Close the file.


UTL_FILE.fclose(l_file);

EXCEPTION
WHEN OTHERS THEN
UTL_FILE.fclose(l_file);
END;
/

===================================================================================
=========
DEPT
DEPTNO PK

EMP
DEPTNO FK

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy