Oracle Notes
Oracle Notes
--------
=> Data represents unprocessed and unorganized raw facts that doesn't carray
any mearning
INFORMATION :-
---------------
DATABASE :-
-----------
Types of Databases :-
-----------------------
=> 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 :-
--------
USER--------------DBMS------------------DB
Evolution of 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
=> Every table must contain primary key to uniquely identify the records
Ex :- ACCNO,EMPID,AADHARNO,PANNO,VOTERID
RDBMS features :-
------------------
RDBMS softwares :-
-------------------
ORDBMS :-
----------
ORDBMS softwares :-
--------------------
ORACLE upto 7 ver RDBMS
ORACLE from 8 ver ORDBMS
POSTGRESQL
18-JUL-24
Analysis
Design
Develop
Test
Deploy/Implement
Maintain
Design :-
-----------
Development :-
--------------
Developer DBA
Testing :-
---------
1 manual
2 automation using a tool called selenium
Deployment / Implemenation :-
-----------------------------
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.
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.
1 ON PREMISES
2 ON CLOUD
=> In " ON CLOUD " db is deployed in the server managed by cloud service provider
like amazon,microsoft,google,oracle etc.
SERVER :-
---------
CLIENT :-
------------
1 connects to server
2 submit requests to server
3 receives response from server
client tool :-
20-jul-24
SQL :-
-------
USER----SQLPLUS--------------SQL---------ORACLE---------DB
USER----MYSQLWORKBENCH-------SQL----------MYSQL---------DB
USER----SSMS----------------SQL-----------SQL SERVER----DB
USER---PGADMIN--------------SQL-----------POSTGRESQL------DB
SQL
22-jul-24
SCHEMA :-
----------
SERVER
DATABASE
USER (SCHEMA)
TABLES (SCHEMA OBJECTS)
DATA
SERVER
ORCL
SYS / MANAGER (DBA)
SYSTEM / MANAGER (DBA)
=> to connect to oracle open sqlplus and enter username and password
USERNAME :- SYSTEM
PASSWORD :- MANAGER
OR
syn :-
Changing 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)
---------
Droping user :-
---------------
ex :-
DOWNLOAD :-
----------
https://www.oracle.com/in/database/technologies/xe-downloads.html
SERVER
ORCL
SYS
SYSTEM
BATCH430
NARESH
23-jul-24
DATATYPES IN ORACLE :-
----------------------
DATATYPES
CHAR(SIZE) :-
-------------
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 :-
------------
ex :- NAME VARCHAR2(10)
SACHIN - - - -
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 :-
-------
EX :- REVIEW LONG
CLOB :-
--------
ex :- TEXT CLOB
=> allows unicode chars (65536 chars) that includes all ascii chars and
chars belongs to different languages.
NUMBER(P) :-
------------
ex :- EMPID NUMBER(4)
10
100
1000
10000 => NOT ALLOWED
PHONE NUMBER(10)
AADHARNO NUMBER(12)
ACCNO NUMBER(11)
NUMBER(P,S) :-
---------------
ex :- 1 SALARY NUMBER(7,2)
5000
5000.55
50000.55
500000.55 => NOT ALLOWED
2 SAVG NUMBER(5,2)
3 BALANCE NUMBER(15,4)
DATE :-
-------
EX :- DOB DATE
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
BINARY :-
---------
=> binary types are used for storing multimedia objects like audio,video,images
=> oracle supports 2 binary types
=> 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 :-
-------------------
Rules :-
--------
EX :- 123CUST invalid
CUST 123 invalid
CUST*123 invalid
CUST_123 valid
Example :-
EMP
EMPID ENAME JOB SAL HIREDATE DEPTNO
DESC :- (DESCRIBE)
--------
EMPID NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(10)
SAL NUMBER(7,2)
HIREDATE DATE
DEPTNO NUMBER(2)
1 single row
2 multiple rows
Ex :-
=> 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.
=> INSERT comamnd can be executed multiple times with different values
by using variables prefixed with "&".
ex :-
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 :-
------------------
method 1 :-
-----------
method 2 :-
-----------
Assignment :-
--------------
CUST
CUSTID NAME GENDER DOB EMAILID PHONE ADDR STATE AADHARNO PANNO
DISPLAYING DATA :-
-------------------
Syntax :-
SQL = ENGLISH
QUERIES = SENTENCES
CLAUSES = WORDS
Examples :-
Operators in ORACLE :-
----------------------
WHERE clause :-
----------------
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 :-
WHERE DEPTNO != 30 ;
Compound condition :-
---------------------
Examples :-
=> employees working for 20th dept and earning more than 5000 ?
=> employees earning more than 5000 and less than 10000 ?
=> 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 ;
SELECT *
FROM EMP
WHERE JOB='CLERK' OR JOB='MANAGER' AND SAL>5000 ;
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
SELECT *
FROM STUDENT
WHERE S1<35 OR S2<35 OR S3<35 ;
IN operator :-
--------------
Ex :-
BETWEEN operator :-
--------------------
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
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
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 :-
-----------------
wildcard chars :-
------------------
examples :-
=>
CUST
CID CNAME
10 SACHIN_TENDULKAR
11 VIRAT%KOHLI
12 MAHENDRA_SINGH_DHONI
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.
the char that immediately follows "\" is not treated as wildcard char
and it is treated search char.
30-jul-24 :-
-------------
PAGESIZE :-
------------
IS operator :-
---------------
SELECT EMPNO,ENAME,SAL,COMM
FROM EMP
WHERE COMM IS NULL ;
SELECT EMPNO,ENAME,SAL,COMM
FROM EMP
WHERE COMM IS NOT NULL ;
SUMMARY :-
Question :-
SELECT *
FROM EMP
WHERE JOB IN ('CLERK','MAN%') ;
A ERROR
B RETURNS CLERK,MANAGER
C RETURNS ONLY CLERK
D NONE
ANS :- C
ANS :- B
USER_TABLES :-
---------------
list of tables ?
ALL_USERS :-
------------
SELECT USERNAME
FROM ALL_USERS
WHERE CREATED BETWEEN '01-JUL-24' AND '31-JUL-24' ;
ALIAS :-
--------
Examples :-
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 , ----- ;
Examples :-
SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY ENAME ASC ;
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
SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY HIREDATE ASC ;
note :-
=> 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
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
DISTINCT :-
-----------
Examples :-
10
20
30
CLERK
MANAGER
ANALYST
SALESMAN
PRESIDENT
01-AUG-24
FETCH clause :-
---------------
syntax :-
---------
SELECT columns
FROM tabname
[WHERE cond]
[ORDER BY ---]
[OFFSET ] FETCH FIRST/NEXT <n> ROWS ONLY ;
SELECT EMPNO,ENAME,SAL
FROM EMP
FETCH FIRST 5 ROWS ONLY ;
SELECT EMPNO,ENAME,SAL
FROM EMP
OFFSET 4 ROWS FETCH NEXT 1 ROW ONLY ;
SELECT EMPNO,ENAME,SAL
FROM EMP
ORDER BY SAL DESC
FETCH FIRST 5 ROWS ONLY ;
SAL
----------
5000
3000
2975
SELECT EMPNO,ENAME,SAL,HIREDATE
FROM EMP
ORDER BY HIREDATE ASC
FETCH FIRST 3 ROWS ONLY ;
SUMMARY :-
INSERT
UPDATE
DELETE
INSERT ALL
MERGE
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 :-
-------------------
Syntax :-
UPDATE <tabname>
SET colname = value , colname = value , -------
[WHERE cond] ;
examples :-
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 ;
DELETE command :-
------------------
CREATE
ALTER
DROP
TRUNCATE
RENAME
FLASHBACK
PURGE
Example 1 :-
Example 2 :-
SELECT * FROM A ;
10
20
ALTER command :-
----------------
1 add columns
2 drop columns
3 rename column
4 modify column
changing datatype
changing size
Adding columns :-
-----------------
Ex :-
1 row updated
Droping column :-
------------------
Ex :-
Renaming a column :-
---------------------
Ex :-
=> rename column comm to bonus ?
Modifying a column :-
---------------------
NOTE :-
03-aug-24
DROP command :-
----------------
Ex :-
=> 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.
SQL>SHOW RECYCLEBIN
FLASHBACK command :-
--------------------
Ex :-
=> table is restored with columns and rows that exists before drop
PURGE command :-
-----------------
Ex :-
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.
EX :-
DELETE VS TRUNCATE :-
--------------------
DELETE TRUNCATE
1 DML DDL
6 slower faster
5-aug-24
RENAME command :-
-----------------
Ex :-
ALIAS RENAME
1 temporary permanent
=> 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() :-
----------
UPPER(arg)
string => 'hello'
column => ename
ex :-
what is DUAL ?
LOWER() :-
-----------
LOWER(arg)
Ex :-
SELECT *
FROM EMP
WHERE ENAME='BLAKE' ; => no rows
SELECT *
FROM EMP
WHERE UPPER(ENAME) = 'BLAKE' ;
INITCAP() :-
-------------
INITCAP(arg)
Ex :-
LENGTH() :-
------------
LENGTH(arg)
Ex :-
SUBSTR() :-
-----------
SUBSTR(string,start,[length])
ex :-
SUBSTR('HELLO WELCOME',1,5) => HELLO
SUBSTR('HELLO WELCOME',10,3) => COM
SUBSTR('HELLO WELCOME',7) => WELCOME
SELECT EMPNO,ENAME,
SUBSTR(ENAME,1,3)||SUBSTR(EMPNO,1,3)||'@tcs.com' AS EMAILID
FROM EMP ;
INSTR() :-
----------
INSTR(string,char,[start,occurance])
ex :-
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
=>
CUST
CID CNAME
10 SACHIN TENDULKAR
11 ROHIT SHARMA
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
ex :-
=>
ACCOUNTS
ACCNO BAL
12345678963 10000
LPAD('X',4,'X')||SUBSTR(ACCNO,-4,4)
=> display ENAME SAL ?
***
****
*****
07-AUG-24
LTRIM,RTRIM,TRIM :-
-------------------
ex :-
REPLACE() :-
-------------
REPLACE(str1,str2,str3)
ex :-
SELECT *
FROM EMP
WHERE LENGTH(ENAME) - LENGTH(REPLACE(ENAME,'a','')) = 2 ;
5 3
ex :- adams
=>
ENAME CHAR(10)
j a m e s - - - - -
TRANSLATE() :-
--------------
TRANSLATE(str1,str2,str3)
ex :-
E => A
L => B
O => C
SELECT ENAME,
TRANSLATE(SAL,'0123456789','$bT*k@G^#%') AS SAL
FROM EMP ;
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() :-
---------
ABS(number)
Ex :-
ABS(-10) => 10
ABS(10) => 10
POWER() :-
----------
POWER(num1,num2)
Ex :-
POWER(3,2) => 9
SQRT() :-
---------
SQRT(number)
Ex :-
SQRT(16) => 4
SIGN() :-
---------
SIGN(10) => 1
SIGN(-10) => -1
SIGN(10-10) => 0
MOD() :-
--------
MOD(num1,num2)
Ex :-
MOD(10,2) => 0
ROUND
TRUNC
CEIL
FLOOR
ROUND :-
--------
ROUND(number,[decimal places])
ex :-
ROUND(38.5648) => 39
38---------------------38.5-----------------------39
ROUND(38.4567) => 38
300-------------------350----------------------400
380-------------------385-----------------------390
ROUND(386,-3) => 0
0----------------------500-------------------------1000
=>
TRUNC() :-
-----------
TRUNC(number,[decimal places])
ex :-
TRUNC(38.9) => 38
TRUNC(38.5678,2) => 38.56
TRUNC(386,-2) => 300
TRUNC(999,-3) => 0
CEIL() :-
---------
CEIL(number)
ex :-
CEIL(3.1) => 4
FLOOR() :-
----------
FLOOR(number)
Ex :-
FLOOR(3.9) => 3
DATE functions :-
-----------------
rounding dates :-
------------------
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
01-AUG-24--------------------15-AUG---------------------------01-SEP-24
04-AUG-24-----------------------THU------------------------------11-AUG-24
08-AUG-24-----------------------12:00PM--------------------------09-AUG-24
09-aug-24
SCENARIO :-
-----------
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.
ADD_MONTHS() :-
----------------
ADD_MONTHS(DATE,NUMBER)
Ex :-
scenario :-
GOLD_RATES
DATEID RATE
01-JAN-20 ?
02-JAN-20 ?
09-JUN-24 ?
SELECT *
FROM GOLD_RATES
WHERE TRUNC(DATEID) BETWEEN TRUNC(ADD_MONTHS(SYSDATE,-1)) AND TRUNC(SYSDATE) ;
SELECT *
FROM EMP
WHERE TRUNC(HIREDATE) > TRUNC(ADD_MONTHS(SYSDATE,-60));
MONTHS_BETWEEN() :-
-----------------
MONTHS_BETWEEN(DATE1,DATE2)
Ex :-
MONTHS_BETWEEN(SYSDATE,'09-AUG-23') => 12
LAST_DAY() :-
-------------
LAST_DAY(DATE)
Ex :-
NEXT_DAY() :-
-------------
NEXT_DAY(DATE,DAY)
Ex :-
Questions :-
CONVERSION :-
-------------
1 implicit conversion
2 explicit conversion
Implicit conversion :-
----------------------
Ex 1 :-
Ex 2 :-
SQL>CREATE TABLE D(F1 DATE);
10-aug-24
Explicit conversion :-
-----------------------
1 TO_CHAR
2 TO_DATE
3 TO_NUMBER
FORMATS :-
-----------
MM => 08
MON => AUG
MONTH => AUGUST
JAN-MAR 1
APR-JUN 2
JUL-AUG 3
OCT-DEC 4
SELECT ENAME,
TO_CHAR(HIREDATE,'YYYY') AS YEAR_OF_JOIN ,
TO_CHAR(HIREDATE,'MONTH') AS MONTH
FROM EMP ;
SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'D') = 1 ;
SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'YYYY') IN (1980,1983,1985) ;
SELECT *
FROM EMP
WHERE MOD(TO_CHAR(HIREDATE,'YYYY'),4) = 0 ;
SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'MM') IN (1,4,12) ;
SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'YYYY') = 1981
AND
TO_CHAR(HIREDATE,'Q') = 2 ;
NOTE :-
=> by default oracle displays date but to display date & time use TO_CHAR
=>
SELECT ENAME,
TO_CHAR(HIREDATE,'YYYY-MM-DD HH:MI:SS AM') AS HIREDATE
FROM EMP ;
=> numbers are converted to char type to display numbers in different formats
TO_CHAR(NUMBER,'FORMAT')
FORMATS :-
----------
Ex :-
SELECT ENAME,
TO_CHAR(SAL,'L9G999') AS SAL
FROM EMP ;
SMITH $800
ALLEN $1,600
12-aug-24
TO_DATE(string,'format')
string => '12-aug-24'
'08/12/24'
Ex :-
O/P :- 19-APR-25
O/P := 04-OCT-24
SELECT TO_CHAR(TO_DATE('15-AUG-1947','DD-MON-YYYY'),'DAY')
FROM DUAL ;
O/P :- FRIDAY
TO_NUMBER(string,'format')
Ex :-
O/P :- 6000
Special :-
-----------
NVL() :-
---------
NVL(arg1,arg2)
Ex :-
ASCII() :-
-----------
ASCII(char)
Ex :-
CHR(ASCII VALUE)
Ex :-
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= 100 ;
SELECT LEVEL
FROM DUAL
WHERE MOD(LEVEL,2) = 0
CONNECT BY LEVEL <= 20 ;
ascii char
1 ?
2 ?
65 A
97 a
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 ;
*
**
***
****
*****
SELECT RPAD('*',LEVEL,'*')
FROM DUAL
CONNECT BY LEVEL < =10 ;
*
***
*****
13-AUG-24
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 ;
=> 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.
ex :-
SQL>SELECT DEPTNO,ENAME,SAL,
DENSE_RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) AS RNK
FROM EMP ;
Ex :-
SELECT EMPNO,ENAME,SAL,
LAG(SAL,1) OVER (ORDER BY EMPNO ASC) AS PREV_SAL
FROM EMP ;
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 ;
SELECT EMPNO,ENAME,HIREDATE,
HIREDATE - LAG(HIREDATE,1) OVER (ORDER BY HIREDATE ASC) AS DAYS
FROM EMP ;
=> GROUP functions process multiple rows and returns one value
MAX
MIN
SUM
AVG
COUNT
COUNT(*)
MAX() :-
---------
MAX(arg)
COLNAME
Ex :-
MIN(colname)
Ex :-
SUM() :-
---------
SUM(colname)
Ex :-
29000------------29050--------------29100
=> after rounding display total sal with thousand seperator and currency symbol ?
16-AUG-24
SUM(SAL) = 12000
SUM(SAL+COMM) = 3500
SUM(SAL) = 12000
SUM(SAL+NVL(COMM,0)) = 12500
AVG() :-
----------
AVG(colname)
Ex :-
COUNT() :-
-----------
COUNT(colname)
Ex :-
SQL>SELECT COUNT(COMM) FROM EMP ; => 4 => nulls are not counted
COUNT(*) :-
----------
T1
F1
10
NULL
20
NULL
30
COUNT(F1) => 3
COUNT(*) => 5
SELECT COUNT(*)
FROM EMP
WHERE HIREDATE BETWEEN '01-JAN-1981' AND '31-DEC-1981' ;
WHERE HIREDATE LIKE '%81' ;
SELECT COUNT(*)
FROM EMP
WHERE TO_CHAR(HIREDATE,'dy') = 'sun' ;
TO_CHAR(HIREDATE,'fmday') = 'sunday' ;
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 :-
------------------
1 simple case
2 searched case
simple case :-
--------------
Ex 1 :-
SELECT ENAME,
CASE JOB
WHEN 'CLERK' THEN 'WORKER'
WHEN 'MANAGER' THEN 'BOSS'
WHEN 'PRESIDENT' THEN 'BIG BOSS'
ELSE 'EMPLOYEE'
END AS JOB
FROM EMP ;
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
SELECT ENAME,SAL,
CASE
WHEN SAL>3000 THEN 'HISAL'
WHEN SAL<3000 THEN 'LOSAL'
ELSE 'AVGSAL'
END AS SALRANGE
FROM EMP ;
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
1 column level
2 table level
column level :-
---------------
NOT NULL :-
------------
Ex :-
19-aug-24
UNIQUE :-
----------
ex :-
PRIMARY KEY :-
--------------
Ex :-
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 :-
CHECK :-
---------
CHECK(condition)
20-aug-24
FOREIGN KEY :-
--------------
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.
=> after declaring foreign key a relationship is established between two tables
called parent/child relationship.
DEFAULT :-
----------
=> while inserting if we skip hiredate then oracle inserts default value.
1 A 20-AUG-24
2 B 01-JAN-24
3 C
Assignment :-
ACCOUNTS
ACCNO ACTYPE BAL
Rules :-
--------
TRANSACTIONS
TRID TTYPE TDATE TAMT ACCNO
Rules :-
---------
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
PRODUCTS
PRODID PNAME PRICE MFD_DT EXP_DT
10 A 50 01-AUG-24 01-JAN-24 INVALID
21-aug-24
=> 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.
Ex 2 :-
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
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.
A UNIQUE
B CHECK
C NOT NULL
D FOREIGN KEY
E PRIMARY KEY
ANS :- C
NOTE :- primary key cannot be added to the column that already contains
duplicates & nulls
=> if check constraint added with NOVALIDATE then oracle will not validate
existing data
and it validates only new data.
=> add fk to dno that refers dept table primary key i.e. deptno ?
22-AUG-24
USER_CONSTRAINTS :
-------------------
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 :-
----------------------
Ex :-
NOTE :-
CASCADE option :-
-----------------
DROP TABLE DEPT CASCADE CONSTRAINTS ; => drops table with dependent foreign key
DELETE RULES :-
---------------
ON DELETE NO ACTION :-
----------------------
scenario :-
ACCOUNTS
ACCNO ACTYPE
100 S
101 C
LOANS
ID TYPE AMT ACCNO
1 H 40 100
2 C 10 100
ON DELETE CASCADE :-
--------------------
=> if parent row is deleted then it is deleted along with child rows.
=> if parent row is deleted then it is deleted but child rows are not deleted but
fk
will be set to null.
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.
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 :-
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
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,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
SELECT columns
FROM tab1 INNER JOIN tab2
ON join cond
INNER JOIN tab3
ON join cond
------- ;
ex :-
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 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
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
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 ;
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.
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
SMITH FORD
ALLEN BLAKE
JONES KING
BLAKE KING
FORD JONES
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
=> 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
=> 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
SELECT E.ENAME,D.DNAME
FROM EMP E FULL OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO ;
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
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 and also display
employees not assigned to any project ?
=> cross join returns cross product or cartesian product of two tables
A = 1,2
B = 3,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
=================================================================================
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
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 :-
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
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.
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
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
=> display dept wise and with in dept job wise total sal ?
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 ?
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 ;
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 ;
GROUPING_ID() :-
----------------
=> grouping_id function takes group by columns and returns subtotal belongs to
which group by column
ex :- GROUPING_ID(DEPTNO,JOB)
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
SELECT columns
FROM tab1 INNER JOIN tab2
ON join cond
GROUP BY colname ;
SELECT D.DNAME,SUM(E.SAL)
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
GROUP BY D.DNAME ;
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
===============================================================================
29-aug-24
Types of sub-queries :-
--------------------
1 Non co-related
2 co-related
3 INLINE views / CTEs
4 scalar sub-queries
SELECT columns
FROM tabname
WHERE colname OP (SELECT STATEMENT) ;
=> OP must be any relational operator like > >= < <= = <>
Examples :-
SELECT *
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE ename='BLAKE') ;
----------------------------------------
2850
SELECT *
FROM emp
WHERE hiredate < ( SELECT hiredate FROM emp WHERE ename='KING') ;
---------------------------------------------
17-NOV-81
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
SELECT ename
FROM emp
WHERE hiredate = (SELECT MIN(hiredate) FROM emp) ;
------------------------------
17-DEC-80
SELECT MAX(sal)
FROM emp
WHERE sal <> (SELECT MAX(sal) FROM emp) ;
------------------------
5000
SELECT ename,sal
FROM emp
WHERE sal = (SELECT MAX(sal)
FROM emp
WHERE sal <> (SELECT MAX(sal) FROM emp)) ;
DELETE
FROM emp
WHERE hiredate = (SELECT MIN(hiredate) FROM emp) ;
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) ;
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' ;
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
1 to display data from one table and condition based on another table then
use sub-query or join
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.
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
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
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
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
31-aug-24
ROWID :-
--------
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 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 :-
----------------
SELECT columns
FROM (SELECT statement) <ALIAS>
WHERE condition ;
FROM
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
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 ;
SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP
WHERE RNK <= 5 ; => ERROR
SELECT *
FROM ( SELECT EMPNO,ENAME,SAL,
DENSE_RANK() OVER (ORDER BY SAL DESC) AS RNK
FROM EMP ) E
WHERE RNK<=5 ;
METHODS :-
2-SEP-24
ROWNUM :-
---------
=> returns record numbers for the records return by select stmt.
=> rownum is also a psuedo column
=> 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 :-
SELECT EMPNO,ENAME,SAL
FROM EMP
WHERE ROWNUM <= 5 ;
SELECT EMPNO,ENAME,SAL
FROM EMP
WHERE ROWNUM = 5 ;
NOTE :-
SELECT *
FROM (SELECT ROWNUM AS RNO,EMPNO,ENAME,SAL FROM EMP) E
WHERE RNO = 5 ;
WHERE MOD(RNO,2) = 1 ;
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 :-
---------------------
Ex 1 :-
Ex 2 :-
10 8750
20 10875
30 9400
10 8750 29025
20 10875 29025
30 9400 29025
PCT = (DEPT_TOTAL/TOTAL)*100
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 :-
-----------------
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 :-
================================================================================
=> a new table is created with name EMP11 and all the rows & cols of emp table
copied to emp11.
SYSTEM/MANAGER :-
----------------
Ex :-
MERGE command :-
------------------
Ex :-
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
04-SEP-24
DATABASE TRANSACTIONS :-
------------------------
ex :- money transfer
acct1--------------1000------------------>acct2
update1 update2
(bal=bal-1000) (bal=bal+1000)
=> every txn has a begin point and and end point
=> 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 :-
Ex 2 :-
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
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
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
3
UPDATE BATCH430.EMP 4 UPDATE EMP
SET SAL=2000 SET SAL=3000
WHERE EMPNO = 7499; WHERE EMPNO = 7369 ;
--------wait------- -------wait--------
============================deadlock=======================================
5 ERROR
===================================================================================
DATABASE SECURITY :-
---------------------
SERVER
DATABASE (USER)
TABLE (PRIVILEGES)
ROW & COLS (VIEWS)
CREATING USERS :-
----------------
SYSTEM :-
---------
PRIVILEGES :-
-------------
BATCH430 :-
------------
VIJAY :-
--------
VIJAY :-
--------
REVOKE command :-
------------------
BATCH430 :-
----------
USER_TAB_PRIVS_MADE :-
----------------------
USER_TAB_PRIVS_RECD :-
---------------------
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 virtual table because it doesn't store data and doesn't occupy
memory and it always derives data from base table.
1 to provide security
2 to reduce complexity
1 simple views
2 complex views
simple views :-
---------------
SYSTEM :-
--------
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 ;
VIJAY :-
---------
SQL>CREATE VIEW V2
AS
SELECT EMPNO,ENAME,JOB,DEPTNO
FROM EMP
WHERE DEPTNO = 20 ;
complex views :-
----------------
=> with the help of views complex queries can be converted into simple queries.
Ex 1 :-
=> after creating view , whenever we want data from emp & dept tables then
instead of writing join query then write the simple query as follows
Ex 2 :-
=> after creating view whenever we want dept wise summary then execute the
following query
simple complex
USER_VIEWS :-
------------
Droping :-
-----------
DROP VIEW V1 ;
=> 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.
SYSTEM :-
---------
BATCH430 :-
----------
after creating synonym instead of using table name use synonym name in
SELECT / INSERT / UPDATE / DELETE queries.
SQL>SELECT * FROM E ;
BATCH430 :-
----------
VIJAY :-
---------
QUESTION :-
-----------
SQL>RENAME EMP TO E ;
synonym alias
1 permanent not permanent
USER_SYNONYMS :-
-----------------
Droping :-
---------
SQL>DROP SYNONYM E ;
Question :-
-------------
SEQUENCES :-
-------------
Ex 1 :-
SQL>CREATE SEQUENCE S1
START WITH 1
INCREMENT BY 1
MAXVALUE 5 ;
using sequence :-
------------------
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;
10-SEP-24
Ex 3 :-
BILL
BILLNO BDATE AMOUNT
DMART/0924/1
/2
CREATE SEQUENCE S5
START WITH 1
INCREMENT BY 1
MAXVALUE 9999;
CYCLE :-
---------
=> 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.
CACHE size :-
-------------
=> 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.
=> above command returns error when executed what could be the reason ?
USER_SEQUENCES :-
----------------
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
Droping :-
----------
SQL>DROP SEQUENCE S1 ;
INDEX :-
-------
Types of Indexes :-
--------------------
1 BTREE indexes
simple
unique
2 BITMAP indexes
EMP 3000
SAL
3000
1000
1500 2000 4000
4000
3000 1000 * 2500 * 4000 * 5000 *
2500 1500 * 3000 *,*
2000 2000 *
5000
UNIQUE INDEX :-
--------------
=> unique index doesn't allow duplicate values into the column on which
index is created.
G Q
NOTE :-
BITMAP indexes :-
------------------
=> BITMAP indexes created on low cardinality columns i.e. columns that contains
less distinct values (<200).
EX :- JOB,DEPTNO,GENDER
Ex :-
=> 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.
BTREE BITMAP
USER_INDEXES :-
---------------
SELECT INDEX_NAME,INDEX_TYPE
FROM USER_INDEXES
WHERE TABLE_NAME='EMP' ;
Droping :-
------------
SQL>DROP INDEX I1 ;
SERVER
DATABASE
USER
TABLE
ROWS & COLS
CONSTRAINTS
INDEXES
TRIGGERS
VIEW
SYNONYM
SEQUENCE
SQL
===================================================================================
============
PL/SQL
======
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.
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.
1 Anonymous Blocks
2 Named Blocks
procedures
functions
packages
triggers
Anonymous Blocks :-
-------------------
DECLARE
<declaration-part>; OPTIONAL
BEGIN
statements;
END;
/ => compiled & executed
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
1 EDITORS
2 IDEs (Integrated Development Environment)
EDITOR IDE
COMPILING NO YES
EXECUTING NO YES
DEBUGGING NO YES
using notepad :-
---------------
BEGIN
DBMS_OUTPUT.PUT_LINE('HELLO WELCOME');
END;
/
SQL>@C:\ORACLE\"PROG1.SQL"
Datatypes in PL/SQL :-
---------------------
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
Declaring variable :-
----------------------
VARIABLENAME DATATYPE(SIZE);
Ex :-
X NUMBER(4);
S VARCHAR2(10);
D DATE;
B BOOLEAN;
Ex :-
X := 100;
S := 'HELLO';
D := SYSDATE;
B := TRUE;
DECLARE
a NUMBER(4);
b NUMBER(4);
c NUMBER(5);
BEGIN
a := 100;
b := 200;
c := a+b;
DBMS_OUTPUT.PUT_LINE(c);
END;
/
1 a := &a;
a := 100;
2 a := &x;
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 :-
-------
DECLARE
d DATE;
BEGIN
d := '&date';
DBMS_OUTPUT.PUT_LINE(TO_CHAR(d,'day'));
END;
/
o/p :- wednesday
=> wap to input name and print first name,middle name,last name ?
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() :-
------------------
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
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;
/
=> From pl/sql to work with db execute sql commands from pl/sql program.
=> the following commands can be executed from pl/sql program.
Ex :-
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;
/
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;
/
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;
/
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;
/
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
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
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 :-
---------
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 :-
-----------
ex :- r emp%ROWTYPE;
r
empno ename job mgr hiredate sal comm deptno
7844 TURNER SALESMAN 8-SEP-81 1500 0 30
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 :-
--------
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;
WHILE loop :-
-------------
WHILE(cond)
LOOP
statements;
END LOOP;
FOR loop :-
----------
Ex :-
FOR i IN 1..10
LOOP
statments;
END LOOP;
Examples :-
DECLARE
x NUMBER(2) := 1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(x);
x := x+1;
EXIT WHEN x > 20;
END LOOP;
END;
/
DECLARE
x NUMBER(2) := 1;
BEGIN
WHILE(x<=20)
LOOP
DBMS_OUTPUT.PUT_LINE(x);
x := x+1;
END LOOP;
END;
/
BEGIN
FOR x IN 2..20
LOOP
DBMS_OUTPUT.PUT_LINE(x);
END LOOP;
END;
/
18-sep-24
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;
/
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;
/
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;
/
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;
/
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 :-
----------
1 DECLARE CURSOR
2 OPEN CURSOR
3 FETCH RECORD FROM CURSOR
4 CLOSE CURSOR
Declaring cursor :-
-------------------
CURSOR <NAME> IS SELECT STATEMENT ;
Opening cursor :-
----------------
OPEN <cursor-name>;
Ex :- OPEN C1;
=> 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 :-
---------
%NOTFOUND :-
------------
%ROWCOUNT :-
-------------
Examples :-
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;
/
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;
/
Ex :-
FOR r IN C1
LOOP
statements;
END LOOP;
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;
/
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;
/
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;
/
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
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() :-
---------------
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
CUSTS CUSTT
CID CNAME CID FNAME MNAME LNAME
10 SACHIN RAMESH TENDULKAR
11 MAHENDRA SINGH DHONI
=> 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.
C1 SYS_REFCURSOR;
---------
CLOSE C1;
------
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;
/
3 static dynamic
Implicit cursor :-
==================
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.
Ex 1 :-
X num_array ;
X(1) := 10;
X(2) := 20;
X(10) := 100;
Ex 2 :-
S string_array ;
S(1) := 'ABC';
S(2) := 'XYZ';
S(3) := 'KLM'
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
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 :-
1 where deptno = i*10 this logic will work for dept table but not for other
tables.
BULK COLLECT :-
---------------
=> using BULK COLLECT we can fetch all the required data from table
and assign that data to collection.
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 :-
---------------------
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;
/
CURSOR COLLECTION
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;
/
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;
/
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;
/
================================================================================
25-sep-24
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);
=> 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;
/
1 system defined
2 user defined
system defined :-
------------------
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;
/
Example :-
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 :-
-----------------------
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;
/
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;
/
===================================================================================
==========
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.
=> 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.
parameters :-
-------------
1 IN (default)
2 OUT
3 IN OUT
MAIN PROCEDURE
X ====================> A (IN)
Y <=================== B (OUT)
Execution :-
------------
1 sql prompt
2 another pl/sql prog
3 front end applications
SQL>EXECUTE procname ;
Ex :- SQL>EXECUTE raise_salary ;
Execution :-
-----------
SQL>EXECUTE raise_salary(pamt=>1000,peno=>7369);
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.
=> while calling procedure if we don't pass value to pamt then oracle assigns
default value
Execution :-
SQL>EXECUTE raise_salary(peno=>7369,pnewsal=>:K);
SQL>PRINT :K
28-sep-24
CUSTS CUSTT
CID CNAME CID FNAME MNAME LNAME
10 SACHIN RAMESH TENDULKAR
11 MAHENDRA SINGH DHONI
=> 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.
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;
/
Execution :-
1 SQL commands
2 another pl/sql prog
3 front-end
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 :-
SELECT *
FROM emp
WHERE IS_LEAP(TO_CHAR(hiredate,'YYYY')) = 'leap year' ;
=> 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 :-
30-SEP-24
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 :-
procedures functions
USER_SOURCE :-
==============
=> system table that stores procedures & functions created by user
Droping :-
----------
PACKAGES :-
-----------
Advantages :-
---------------
1 easy to manage :-
---------------
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 :-
-----------------------
1 package specification
2 package body
package specification :-
-----------------------
package body :-
----------------
END;
/
1-OCT-24
ACCOUNTS
ACCNO ACTYPE BAL
TRANSACTIONS
TRID TTYPE TDATE TAMT ACCNO
CREATE SEQUENCE S10
START WITH 1
INCREMENT BY 1
MAXVALUE 9999 ;
specification :-
---------------
package body :-
---------------
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 BODY BANK ; => drops only body but not specification
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.
1 to control dmls/ddls
2 to enforce complex rules and validations
3 to audit day-to-day operations on tables
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 :-
------------------
=> statement level triggers are executed once per the dml.
=> row level triggers are executed once per the row affected by dml.
Examples :-
Testing :-
SQL>UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = 7566 ; => ERROR
Testing :-
----------
Testing :-
SQL>UPDATE EMP SET EMPNO = 9999 WHERE EMPNO = 7844 ; => ERROR
3-oct-24
=> 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.
UPDATE EMP SET SAL=5000 WHERE EMPNO = 100 ; => => :NEW
EMPNO SAL
100 5000
:OLD
EMPNO SAL
100 4000
=> these two variables are allowed only in row level trigger but not allowed in
stmt level triggers
Ex :-
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
Testing :-
----------
CUSTS CUSTT
CID NAME ADDR CID NAME ADDR
Testing :-
----------
ANS :- 12
I
R
B
U
S
A
D
BEFORE STMT
BEFORE ROW
AFTER ROW
AFTER STMT
Compound trigger :-
--------------------
=> using compound trigger we can define multiple triggers in one 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 statement is
begin
DBMS_OUTPUT.PUT_LINE('after stmt');
end after statement;
end;
BEFORE STMT
BEFORE ROW
AFTER ROW
BEFORE ROW
AFTER ROW
AFTER STMT
USER_TRIGGERS :-
----------------
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.
tname VARCHAR2(20);
tname := '&tabname';
=> Dynamic SQL / DDL command that you want to execute shuold be passed as a
string to EXECUTE IMMEDIATE.
Ex 1 :-
Execution :-
SQL>EXECUTE DROP_TABLE('CUSTS');
Ex 2 :-
Execution :-
SQL>EXECUTE DROP_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 :-
-------------------
=> using this package we can create new files,write data into files and read
data from files.
members :-
----------
Directory Object :-
------------------
SYSTEM/MANAGER :-
---------------
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
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;
/
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;
/
=> oracle provided the following two types for storing multimedia objects
like audio,video,images.
BFILE :-
----------
=> BFILE is called external lob because lob is stored outside db but db stores
path
=> to store path in db use function BFILENAME.
Ex :-
BLOB :-
-------
=> BLOB is called internal lob because lob is stored inside db
Ex :-
Execution :-
LENGTH(CPHOTO)
--------------
0
LENGTH(CPHOTO)
--------------
7305
BLOB TO FILE :-
----------------
l_blob_len := DBMS_LOB.getlength(l_blob);
EXCEPTION
WHEN OTHERS THEN
UTL_FILE.fclose(l_file);
END;
/
===================================================================================
=========
DEPT
DEPTNO PK
EMP
DEPTNO FK