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

PLSQL IQ v1.5

Uploaded by

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

PLSQL IQ v1.5

Uploaded by

vedantprocess
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Contents

Case vs Decode: which one is faster? ................................................................................................................................... 2


NVL NVL2 and COALESCE...................................................................................................................................................... 4
Select duplicate records from the table: .............................................................................................................................. 4
Deleting duplicate records: .................................................................................................................................................. 5
PRINT 1 TO 10 NUMBERS IN SQL: ......................................................................................................................................... 5
Nth HIGHEST SALARY:........................................................................................................................................................... 5
TOP N EMPLOYEES BASED ON SALARY: ................................................................................................................................ 5
JOINS:.................................................................................................................................................................................... 5
PROCDURE: ........................................................................................................................................................................... 6
FUNCTION:............................................................................................................................................................................ 7
FUNCTION VS PROCEDURE: .................................................................................................................................................. 7
PRAGMA AUTONOMOUS_TRANSACTION; ........................................................................................................................... 8
TRIGGERS: ............................................................................................................................................................................. 9
COMPOUND Trigger in Oracle 11g: .................................................................................................................................... 10
Virtual tables in Trigger: ..................................................................................................................................................... 10
EXCEPTIONS: ....................................................................................................................................................................... 11
Number to Words using SQL Query: .................................................................................................................................. 13
Count an occurrence of a given character from given string ............................................................................................. 13
Packages: ............................................................................................................................................................................ 13
SAVEPOINT: ........................................................................................................................................................................ 16
Index: .................................................................................................................................................................................. 16
Invisible Indexes in Oracle Database 11g: .......................................................................................................................... 17
Can we create multiple Indexes on Same column? ........................................................................................................... 19
VIEW: .................................................................................................................................................................................. 19
Materialized View:.............................................................................................................................................................. 19
QUERY REWRITE Clause: .................................................................................................................................................... 19
VIEW vs MVIEW: ................................................................................................................................................................. 20
Deterministic Functions:..................................................................................................................................................... 20
Soft parsing Vs Hard Parsing: ............................................................................................................................................. 20
Cursor: ................................................................................................................................................................................ 20
REF Cursor: ......................................................................................................................................................................... 21
Sequence: ........................................................................................................................................................................... 22
Sequence as Default Value in Oracle 12c: ......................................................................................................................... 22
SQL Loader:......................................................................................................................................................................... 22

1|Page
Created by: Nayan
Oracle Architecture: ........................................................................................................................................................... 24
Synonym: ............................................................................................................................................................................ 24
DB Link: ............................................................................................................................................................................... 24
Partitioning: ........................................................................................................................................................................ 24
New Partitioning features in 11g........................................................................................................................................ 27
COLLECTIONS: ..................................................................................................................................................................... 28
BULK Collect and FOR ALL: ................................................................................................................................................. 15
How can I combine multiple rows into a comma-delimited list in Oracle? ....................................................................... 29
Splitting string into multiple rows in Oracle ....................................................................................................................... 29
Table Functions: ................................................................................................................................................................. 29
Pipelined Table Functions: ................................................................................................................................................. 30
Bind Variable: ..................................................................................................................................................................... 30
NO COPY: ............................................................................................................................................................................ 30
For update and No wait:..................................................................................................................................................... 30
On delete cascade: ............................................................................................................................................................. 30
On Delete set null: .............................................................................................................................................................. 30
Oracle 12g features for developers: ................................................................................................................................... 30

Case vs Decode: which one is faster?


1. CASE can work with logical operators other than ‘=’ but DECODE only work with ‘=’
select ename,
case
when sal < 1000 then
'Grade I'
when (sal >= 1000 and sal < 2000) then
'Grade II'
when (sal >= 2000 and sal < 3000) then
'Grade III'
else
'Grade IV'
end sal_grade
from emp
where rownum < 4;

2. CASE can work with searchable sub queries (and predicates)

We can specify any condition that we can do in where clause


select e.ename,
case
when e.ename in ('KING', 'SMITH', 'WARD') then
'Top Bosses'
when exists (select 1 from emp emp1 where emp1.mgr = e.empno) then
'Managers'
else
'General Employees'
end emp_category
from emp e

2|Page
Created by: Nayan
where rownum < 5;

ENAME EMP_CATEGORY
---------- -----------------
SMITH Top Bosses
ALLEN General Employees
WARD Top Bosses
JONES Managers

3. CASE can work as a PL/SQL construct


DECODE can work as a function inside SQL only. CASE can be an efficient substitute for IF-THEN-ELSE in PL/SQL.
declare
grade char(1);
begin
grade := 'b';
case grade
when 'a' then
dbms_output.put_line('excellent');
when 'b' then
dbms_output.put_line('very good');
when 'c' then
dbms_output.put_line('good');
when 'd' then
dbms_output.put_line('fair');
when 'f' then
dbms_output.put_line('poor');
else
dbms_output.put_line('no such grade');
end case;
end;
CASE can even work as a parameter to a procedure call, while DECODE cannot.

4. CASE handles NULL differently


Check out the different results with DECODE vs NULL.

select decode(null,
null, 'NULL',
'NOT NULL') null_test
from dual;
O/P:
NULL
----
NULL
select case null
when null then
'NULL'
else
'NOT NULL'
end null_test
from dual;

NULL_TES
--------
NOT NULL

5. CASE expects datatype consistency, DECODE does not


Compare the two examples below- DECODE gives you a result, CASE gives a datatype mismatch error.
select decode(2,
1, 1,

3|Page
Created by: Nayan
'2', '2',
'3') t
from dual;

T
----------
2
select case 2
when 1 then
'1'
when '2' then
'2'
else
'3'
end
from dual;

when '2' then '2'


*
ERROR at line 2:
ORA-00932: inconsistent datatypes: expected NUMBER got CHAR

Which one is better?

No much difference, CASE looks better

NVL NVL2 and COALESCE


NVL (expr1, expr2 )
If expr1 is null, then NVL returns expr2. If expr1 is not null, then NVL returns expr1.
NVL:
SELECT NVL(COMMISSION_PCT, 0)
FROM EMPLOYEES
WHERE COMMISSION_PCT IS NULL
AND ROWNUM = 1;
NVL2 (expr1, expr2 , expr3 )
If expr1 is null, then NVL2 returns expr3. If expr1 is not null, then NVL2 returns expr2.
NVL2:
SELECT NVL2(COMMISSION_PCT, COMMISSION_PCT, 0)
FROM EMPLOYEES
WHERE COMMISSION_PCT IS NULL
AND ROWNUM = 1;
COALESCE (expr[,expr]…)
Returns the first non-null expression in the expression list.
COALESCE:
SELECT COALESCE(COMMISSION_PCT, 0)
FROM EMPLOYEES
WHERE COMMISSION_PCT IS NULL
AND ROWNUM = 1;

Select duplicate records from the table:


SELECT FIRST_NAME, LAST_NAME, COUNT(*)
FROM EMPLOYEES
GROUP BY FIRST_NAME, LAST_NAME
HAVING COUNT(*) > 1;

4|Page
Created by: Nayan
Deleting duplicate records:
DELETE EMPLOYEES
WHERE ROWID NOT IN
(SELECT MIN(ROWID) FROM EMPLOYEES GROUP BY FIRST_NAME, LAST_NAME)

PRINT 1 TO 10 NUMBERS IN SQL:


SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 10
Or
SELECT LEVEL N FROM DUAL CONNECT BY LEVEL <= 10;

Nth HIGHEST SALARY:


SELECT *
FROM EMPLOYEES E1
WHERE &N - 1 = (SELECT COUNT(DISTINCT SALARY)
FROM EMPLOYEES E2
WHERE E2.SALARY > E1.SALARY)

TOP N EMPLOYEES BASED ON SALARY:


SELECT *
FROM EMPLOYEES E1
WHERE &N - 1 >= (SELECT COUNT(DISTINCT SALARY)
FROM EMPLOYEES E2
WHERE E2.SALARY > E1.SALARY)
USING ROWNUM:
SELECT *
FROM (SELECT * FROM EMPLOYEES ORDER BY SALARY DESC)
WHERE ROWNUM < 3

JOINS:
--JOINS
--INNER JOIN--MATCHING NOT NULL RECORDS
SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
INNER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

--NATURAL JOIN- SAME AS INNER JOIN


SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E NATURAL
JOIN DEPARTMENTS D

SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME


FROM EMPLOYEES E
JOIN DEPARTMENTS D
USING (DEPARTMENT_ID)

--EQUIJOIN
SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E, DEPARTMENTS D
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID;

--OUTER JOIN
SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
LEFT OUTER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME


FROM EMPLOYEES E, DEPARTMENTS D

5|Page
Created by: Nayan
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID(+);

--RIGHT JOIN
SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
RIGHT OUTER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME


FROM EMPLOYEES E, DEPARTMENTS D
WHERE E.DEPARTMENT_ID(+) = D.DEPARTMENT_ID;

--FULL OUTER JOIN


SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
FULL OUTER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

--CROSS JOIN
SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E --107
CROSS JOIN DEPARTMENTS D --27

--SELF JOIN
SELECT E.FIRST_NAME EMPNAME, M.FIRST_NAME MANAGER_NAME
FROM EMPLOYEES E
INNER JOIN EMPLOYEES M
ON E.MANAGER_ID = M.EMPLOYEE_ID;
/*
TABLE1 TABLE2
1 2
2 3
3 4
3 6
5 8
NULL NULL
7

OUTPUT:
1) IJ= 2, 3, 3. 3 rows selected

2) RJ= 2, 3, 3, null, 6, 4, 8. 7 rows selected

3) LJ=2, 3, 3, null, 5, 1, 7. 7 rows selected

4) FO=2, 3, 3, null, null, 6, 4, 8, 5, 1, 7. 11 rows selected

5) cj= 42 rows selected

*/

PROCDURE:
Block of Statements/ Sub Programs used to implement Business Logic

CREATE OR REPLACE PROCEDURE REMOVE_EMP(EMPLOYEE_ID NUMBER)


BEGIN
DELETE FROM EMPLOYEES
WHERE EMPLOYEES.EMPLOYEE_ID = REMOVE_EMP.EMPLOYEE_ID;
DBMS_OUTPUT.PUT_LINE('Employee Deleted');
COMMIT;
END;

6|Page
Created by: Nayan
Example of parameterized procedure:
CREATE OR REPLACE PROCEDURE PRC_EXCEPTION_DEMO1( P_EID IN EMPLOYEES.Employee_Id%TYPE)
IS
V_FN EMPLOYEES.FIRST_NAME%TYPE;
BEGIN
--P_EID:=101; You cannot write since it is IN parameter
SELECT E.FIRST_NAME INTO V_FN FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = P_EID;
DBMS_OUTPUT.PUT_LINE(V_FN);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NO DATA FOUND');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('TOO MANY ROWS');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;

--Call from PLSQL


BEGIN
PRC_EXCEPTION_DEMO1(100);
END;

--Call from Command window/SQL


SQL> set serveroutput on;
SQL> EXEC PRC_EXCEPTION_DEMO1(100);
King
PL/SQL procedure successfully completed

FUNCTION:
It is a set of PL/SQL statements you can call by name; Function should always return a value.
Typically function takes an input, processes and returns the output in other words Functions are normally used for
computations

--FUNCTION
CREATE OR REPLACE FUNCTION FN_SQR(P_NUM IN NUMBER) RETURN NUMBER IS
BEGIN
RETURN (P_NUM * P_NUM);
END;

--Call from SQL query


SELECT FN_SQR(5) FROM DUAL; --SELECT FN_NAME(COLUMN_NAME/EXPRESSION) FROM DUAL;

--Call in PLSQL
DECLARE
V_TEST NUMBER:=FN_SQR(5);
BEGIN
DBMS_OUTPUT.PUT_LINE(V_TEST);
END;

FUNCTION VS PROCEDURE:
• Functions are normally used for computation whereas procedures are normally used for executing
business logic
• Procedure may or may not return value whereas function should return one value
• We can call function within procedure but we cannot call procedure within function
• Function can be called from SQL statement whereas procedure can't be called from the SQL statement
7|Page
Created by: Nayan
• You can have DML (insert, update, delete) OR commit/rollback statements in a function. But, you
cannot call such a function in a SQL query
o Procedure can perform one or more tasks whereas function performs a specific task
o Stored Procedure: supports deferred name resolution. Example while writing a stored procedure that
uses table named tabl1 and tabl2 etc. But those tables do not exist in database is allowed only in during
creation but runtime throws error Function won’t support deferred name resolution.
o Stored procedure returns always integer value by default zero. Whereas function returns type could be
scalar or table or table value
o Stored procedure is pre-compiled execution plan whereas functions are not
Can we use out parameter in function:
Yes, function can take OUT type parameter but the good programing practice is to not use the OUT parameter since
function must return only one value to the calling environment.
Can we use commit in function:
Technically, the answer is yes. You can do that in PLSQL as follows
CREATE OR REPLACE FUNCTION COMMITTEST RETURN NUMBER AS
BEGIN
UPDATE MY_TABLE SET COL = 'x';
COMMIT;
RETURN 1;
END;
/
DECLARE NUMBER N;
BEGIN
N := COMMITTEST();
END;
/
However, you can't do this in SQL query as shown below,
SELECT COMMITTEST() FROM DUAL;

This would be a commit during a query and thus result in a


ORA-14552: Cannot Perform a DDL Commit or Rollback inside a Query or DML

If you still want to use it forcefully in SQL then,


You can do that if you make the function an autonomous transaction. That way it will not be part of the current
transaction anymore.
CREATE OR REPLACE FUNCTION DOIT AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
--... CODE ...
COMMIT;
END;

PRAGMA AUTONOMOUS_TRANSACTION;
Autonomous transactions allow you to leave the context of the calling transaction, perform an independent
transaction, and return to the calling transaction without affecting its state. The autonomous transaction has
no link to the calling transaction, so only committed data can be shared by both transactions.
In simple words, it creates an independent transaction irrespective of the current context.
So whatever (commit/rollback) happens in PAT will be limited to PAT only and not affect actual context in any
way and vice-versa.
8|Page
Created by: Nayan
TRIGGERS:
A trigger is a PLSQL block which gets invoked automatically on occurrence of particular events, which is either
on a table, view, schema, or the database.
Triggers are commonly used to:
• Automatically generate derived column values
• Enforce referential integrity
• Enforce complex business rules
• Provide transparent event logging
• Provide efficient auditing
• Maintain synchronous table replicates
• Gather statistics on table access

PL/SQL Trigger Execution Hierarchy:

The following hierarchy is followed when a trigger is fired.


1) BEFORE statement trigger fires first.
2) Next BEFORE row level trigger fires, once for each row affected.
3) Then AFTER row level trigger fires once for each affected row. These events will alternates between BEFORE
and AFTER row level triggers.
4) Finally the AFTER statement level trigger fires.

Types of Triggers:
1. BEFORE UPDATE, Statement Level: This trigger will insert a record into the table 'product_check' before a SQL update
statement is executed, at the statement level.

CREATE or REPLACE TRIGGER Before_Update_Stat_product


BEFORE
UPDATE ON product
Begin
INSERT INTO product_check
Values('Before update, statement level',sysdate);
END;
/
2. BEFORE UPDATE, Row Level: This trigger will insert a record into the table 'product_check' before each row is updated.

CREATE or REPLACE TRIGGER Before_Upddate_Row_product


BEFORE
UPDATE ON product
FOR EACH ROW <-- Row Level
BEGIN
INSERT INTO product_check
Values('Before update row level',sysdate);
END;
/
3. AFTER UPDATE, Statement Level: This trigger will insert a record into the table 'product_check' after a sql update
statement is executed, at the statement level.

9|Page
Created by: Nayan
CREATE or REPLACE TRIGGER After_Update_Stat_product
AFTER
UPDATE ON product
BEGIN
INSERT INTO product_check
Values('After update, statement level', sysdate);
End;
/
4. AFTER UPDATE, Row Level: This trigger will insert a record into the table 'product_check' after each row is updated.

CREATE or REPLACE TRIGGER After_Update_Row_product


AFTER
insert On product
FOR EACH ROW
BEGIN
INSERT INTO product_check
Values('After update, Row level',sysdate);
END;
/

COMPOUND Trigger in Oracle 11g:


A compound trigger is a single trigger on a table that enables you to specify all above 4 actions in single trigger

CREATE OR REPLACE TRIGGER compound_trigger_name


FOR [INSERT|DELETE]UPDATE [OF column] ON table
COMPOUND TRIGGER
--Executed before DML statement
BEFORE STATEMENT IS
BEGIN
NULL;
END BEFORE STATEMENT;

--Executed before each row change- :NEW, :OLD are available


BEFORE EACH ROW IS
BEGIN
NULL;
END BEFORE EACH ROW;

--Executed aftereach row change- :NEW, :OLD are available


AFTER EACH ROW IS
BEGIN
NULL;
END AFTER EACH ROW;

--Executed after DML statement


AFTER STATEMENT IS
BEGIN
NULL;
END AFTER STATEMENT;
END compound_trigger_name;

Follows keyword:

Virtual tables in Trigger:


:NEW- Contains all the values new values of the table after trigger get executed

10 | P a g e
Created by: Nayan
:OLD- Contains all the values old values of the table before trigger get executed
You normally use the terms in a trigger using :old to reference the old value and :new to reference the new
value. Here is an example from the Oracle documentation linked to above

CREATE OR REPLACE TRIGGER PRINT_SALARY_CHANGES


BEFORE DELETE OR INSERT OR UPDATE ON EMPLOYEES
FOR EACH ROW
DECLARE
SAL_DIFF NUMBER;
BEGIN
SAL_DIFF := :NEW.SALARY - :OLD.SALARY;
DBMS_OUTPUT.PUT('Old salary: ' || :OLD.SALARY);
DBMS_OUTPUT.PUT(' New salary: ' || :NEW.SALARY);
DBMS_OUTPUT.PUT_LINE(' Difference ' || SAL_DIFF);
END;

In this example the trigger fires BEFORE DELETE OR INSERT OR UPDATE :old.sal will contain the salary prior to
the trigger firing and :new.sal will contain the new value.

EXCEPTIONS:
An exception is an error condition (by the run-time system) during a program execution
Types of Exceptions:
Pre-defined Exceptions:
Raised implicitly by Oracle
Non-Predefined Exceptions:
User Defined Exceptions: Raised explicitly by User

Pre-defined Exceptions:
DECLARE
V_FN EMPLOYEES.FIRST_NAME%TYPE;
BEGIN
SELECT E.FIRST_NAME INTO V_FN FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = 1;
DBMS_OUTPUT.PUT_LINE(V_FN);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NO DATA FOUND');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('TOO MANY ROWS');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;

Non-Predefined Exceptions:
PRAGMA EXCEPTION_INIT:
DECLARE
V_SAL EMPLOYEES.SALARY%TYPE;
V_UDE EXCEPTION;
PRAGMA EXCEPTION_INIT(V_UDE,+100);
BEGIN
RAISE_APPLICATION_ERROR(-20654,'MY ERROR');
SELECT E.SALARY INTO V_SAL FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = 1;
EXCEPTION
WHEN V_UDE THEN
DBMS_OUTPUT.PUT_LINE('USER DEFINED EXCEPTION OCCURED');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);

11 | P a g e
Created by: Nayan
END;

RAISE_APPLICATION_ERROR('MY ERROR',-20654);

User Defined Exceptions:


DECLARE
V_SAL EMPLOYEES.SALARY%TYPE;
V_UDE EXCEPTION;
BEGIN
SELECT E.SALARY INTO V_SAL FROM EMPLOYEES E WHERE E.EMPLOYEE_ID = 101;
IF V_SAL > 1000 THEN
RAISE V_UDE; --Raising Exceptions explicitly
ELSE
DBMS_OUTPUT.PUT_LINE(V_SAL);
END IF;
EXCEPTION
WHEN V_UDE THEN
DBMS_OUTPUT.PUT_LINE('USER DEFINED EXCEPTION OCCURED');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;

NAME ANY 5 EXCEPTIONS THAT YOU'VE WORKED ON

1) No_Data_Found: It is raised when a SELECT INTO statement returns no rows.


2) To_Many_Rows: It is raised when a SELECT INTO statement returns more than one row and we
have not used cursor to fetch the rows.
3) InvalId_Curser: It is raised when you try to perform invalid operations on cursor like opening
closed cursor
4) Zero_Divide: It is raised when an attempt is made to divide a number by zero.

5)Dup_Val_On_index:It is raised when duplicate values are attempted to be stored in a column


with unique index

Name and explain any 5 oracle supplied packages:


DBMS_OUTPUT: Used to display the user defined message
UTL_FILE: Used to do IO over the flat files
DBMS_JOB: Used to perform job scheduling and management
DBMS_SQL: Used to execute dynamic queries (used in earlier versions of Oracle before 9i)

UTL_FILE Example:
DECLARE
FILE_RESULT UTL_FILE.FILE_TYPE;
V_OP_FILENAME VARCHAR2(20);
BEGIN
--TO REDIRECT OUTPUT TO THE FILE
--WE NEED TO CONFIGURE USING
--CREATE OR REPLACE DIRECTORY DIR_OUTPUT AS 'D:\UTL_DEMO';
--TO CREATE DIRECTORY PATH
V_OP_FILENAME := 'TESTFILE.TXT';
FILE_RESULT := UTL_FILE.FOPEN('DIR_OUTPUT', V_OP_FILENAME, 'W');
UTL_FILE.PUT_LINE(FILE_RESULT, 'TEST DATA');
END;

We use EXECUTE IMMEDIATE on the later version of Oracle after 8i,

12 | P a g e
Created by: Nayan
CREATE OR REPLACE PROCEDURE PRC_DYN(P_TN VARCHAR2,
P_CN VARCHAR2,
P_VAL VARCHAR2) IS
V_SQL VARCHAR2(100);
V_FN VARCHAR2(100);
BEGIN
V_SQL := 'select ' || P_CN || ' from ' || P_TN || ' where ' || P_CN ||
'=''' || P_VAL || '''';
DBMS_OUTPUT.PUT_LINE(V_SQL);
EXECUTE IMMEDIATE V_SQL
INTO V_FN;
DBMS_OUTPUT.PUT_LINE(V_FN);
END;
It is also being used to execute DDL in procedure

Can we execute DDL in procedure?


Yes, with the help of EXECUTE IMMEDIATE

CREATE OR REPLACE PROCEDURE PRC_DYN IS


V_SQL VARCHAR2(100);
BEGIN
V_SQL := 'create table t1 (c1 varchar2(11))';
DBMS_OUTPUT.PUT_LINE(V_SQL);
EXECUTE IMMEDIATE V_SQL;
END;

Number to Words using SQL Query:


SELECT TO_CHAR (TO_DATE (234, 'j'), 'jsp') FROM DUAL;

Count an occurrence of a given character from given string


SELECT LENGTH('abcbcb') - LENGTH(REPLACE('abcbcb', 'b', NULL)) Cnt
FROM DUAL;

Below query works in 11g and above:


SELECT REGEXP_COUNT('123123123123123', '123', 1, 'i') CNT
FROM DUAL;

If column contains duplicate values so how can we make sure that it shouldn’t allow
duplicate values for further inserts without deleting existing data?
We need add unique key but Oracle will not allow you to do so since the column already has duplicate values
but we can do this with NO VALIDATE option while adding unique key constraint

Packages:
A package is a schema object that groups logically related PL/SQL items such as Functions, Procedures, types,
variables, constants, cursors, and exceptions.
A package is compiled and stored in the database

Why we use Packages or Advantages of using packages:


o Better Performance: When you call any procedure or Function from package for the first time, Oracle
loads the whole package into memory so the subsequent call to any procedure or fun from same
package is being done from local memory rather than from oracle server which reduces network traffic
13 | P a g e
Created by: Nayan
There is only one copy in memory for all users
o Modularity
o Easier Application Design which makes maintaining applications very easy
o Hidden Implementation Details

How will you decide whether any newly created procedure is to be added into the package or to be created
as a standalone procedure?
It depends on the call of the procedure in subsequent program, refer first point from advantages

Can we give grant to specific function or procedure which belongs to package?


No.

Package Specification:
A package specification declares public items like functions and procedures, Here we just define the prototype
of the subprograms and declares the variables
CREATE OR REPLACE PACKAGE PCK_DEMO AS
FUNCTION F_MUL(X INT, Y INT) RETURN INT;
PROCEDURE PROC_MUL(X1 INT, X2 INT, X3 OUT INT);
END PCK_DEMO;

Package Body:
If a package specification declares cursors or subprograms, then a package body is required; otherwise, it is
optional.
CREATE OR REPLACE PACKAGE BODY PCK_DEMO AS
FUNCTION F_MUL(X INT, Y INT) RETURN INT IS
Z INT;
BEGIN
Z := X * Y;
RETURN(Z);
END F_MUL;
PROCEDURE PROC_MUL(X1 INT, X2 INT, X3 OUT INT) IS
BEGIN
X3 := F_MUL(X1, X2);
DBMS_OUTPUT.PUT_LINE(X3);
END PROC_MUL;
END PCK_DEMO;
Forward reference: If you want to use any subprogram into the body, which is supposed to be defined after its
call then declare its prototype before the call as shown in below program,
CREATE OR REPLACE PACKAGE PCK_DEMO AS
PROCEDURE PROC_MUL(X1 INT, X2 INT, X3 OUT INT);
END PCK_DEMO;

CREATE OR REPLACE PACKAGE BODY PCK_DEMO AS


FUNCTION F_MUL(X INT, Y INT) RETURN INT; --Forward reference
PROCEDURE PROC_MUL(X1 INT, X2 INT, X3 OUT INT) IS
BEGIN
X3 := F_MUL(X1, X2);
DBMS_OUTPUT.PUT_LINE(X3);
END PROC_MUL;
FUNCTION F_MUL(X INT, Y INT) RETURN INT IS --Private function
Z INT;
BEGIN
Z := X * Y;
RETURN(Z);
END F_MUL;
14 | P a g e
Created by: Nayan
END PCK_DEMO;
Private functions are those functions which are defined in the specification only and not in Body of the
package, you cannot call such functions outside the package body using package name

How to swap column values:


UPDATE EMPLOYEEs SET FIRST_NAME = LAST_NAME, LAST_NAME = FIRST_NAME;

As you know in row level triggers the values of each column is stored in :OLD and :NEW parameters. For the
above UPDATE statement, Oracle stores the old values of FIRAT_NAME and LAST_NAME in the :OLD parameter
and then update FIRST_NAME with :OLD.LAST_NAME and LAST_NAME with :OLD.FIRST_NAME.

BULK Collect and FOR ALL:

BULK COLLECT: SELECT statements that retrieve multiple rows with a single fetch, improving the speed of data
retrieval
DECLARE
TYPE V_RT IS RECORD(
EMPLOYEE_ID EMPLOYEES.EMPLOYEE_ID%TYPE,
SALARY EMPLOYEES.SALARY%TYPE); --RECORD TYPE VARIABLE
TYPE C_T IS TABLE OF V_RT; --COLLECTION
V_EMP C_T; --OBJECT OF COLLECTION
BEGIN
SELECT EMPLOYEE_ID, SALARY
BULK COLLECT
INTO V_EMP
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 10;
END;

FORALL: INSERTs, UPDATEs, and DELETEs that use collections to change multiple rows of data very quickly
FORALL I IN V_EMP.FIRST .. V_EMP.LAST
INSERT INTO FORALL_TEST VALUES V_EMP(I);

What is the optimal way to copy data from one DB/Table to another DB/Table:
We can do this using BULK collect and FORALL as shown below,
DECLARE
-- DEFINE ARRAY TYPE OF THE NEW TABLE
TYPE NEW_TABLE_ARRAY_TYPE IS TABLE OF NEW_TABLE%ROWTYPE INDEX BY BINARY_INTEGER;

-- DEFINE ARRAY OBJECT OF NEW TABLE


NEW_TABLE_ARRAY_OBJECT NEW_TABLE_ARRAY_TYPE;

-- FETCH SIZE ON BULK OPERATION, SCALE THE VALUE TO TWEAK


-- PERFORMANCE OPTIMIZATION OVER IO AND MEMORY USAGE
FETCH_SIZE NUMBER := 5000;

-- DEFINE SELECT DESIERED COLUMNS STATMENT OF OLD TABLE


CURSOR OLD_TABLE_CURSOR IS
SELECT * FROM OLD_TABLE;
BEGIN
OPEN OLD_TABLE_CURSOR;
LOOP
-- BULK FETCH(READ) OPERATION
FETCH OLD_TABLE_CURSOR BULK COLLECT
INTO NEW_TABLE_ARRAY_OBJECT LIMIT FETCH_SIZE;
EXIT WHEN OLD_TABLE_CURSOR%NOTFOUND;

15 | P a g e
Created by: Nayan
-- DO YOUR BUSINESS LOGIC HERE (IF ANY)

-- BULK INSERT OPERATION


FORALL I IN INDICES OF NEW_TABLE_ARRAY_OBJECT SAVE EXCEPTIONS
INSERT INTO NEW_TABLE VALUES NEW_TABLE_ARRAY_OBJECT (I);
COMMIT;
END LOOP;
CLOSE OLD_TABLE_CURSOR;
END;

Suppose you have 40 million records in the table and you need to delete 15 million record from it, what will
be your approach to do this?

How DML get processed? It stores the data into undo log buffer until we commit the transaction, if you
commit the operation; Oracle flushes the information from the Log Buffer to the online redo log files.
The undo block is used to store the before image of the data, so that the DML statements can be rolled back if
necessary.
You can create temp table and dump the require data into it and truncate the original table and copy back the
required data from temp table.

Step 1: Create copy(backup) of the table with required data (Use Bulk collect and For all to copy data
efficiently)
Step 2: Truncate original table
Step 3: Copy back the required data from backup table (Or delete mail table and rename backup table)

LOGGING or NOLOGGING?
LOGGING is a keyword that used on creating the index, table or tablespace. If we use LOGGING when creating
the object then DML operations on the objects are logged in redo log file. If we use NOLOGGING when creating
the object, in some cases DML operations on the objects are not logged in redo log file.

SAVEPOINT:
If we want some part of the program to be COMMITted and some part to be ROLLBACKed in that scenario we
use SAVEPOINT

**ALL DDL statements are auto committed


**They execute COMMIT before and after the DDL statement get executed
Index:
An index is a performance-tuning method of allowing faster retrieval of records.

Simple Index:
CREATE INDEX EMP_DEPT_IDX
ON EMPLOYEES (first_name);

16 | P a g e
Created by: Nayan
Composite Index:
CREATE INDEX EMP_NAME_IDX
ON EMPLOYEES (FIRST_NAME, LAST_NAME)
COMPUTE STATISTICS;

How Index works?


It is a data structure i.e. B-tree or Hash table which stores key column values of the table since it is being stored
in sorted order which is very easy to search

Types of Indexes:
Cluster and Non Cluster: In Cluster index the actual data is being stored in the Index and in Non-Clustered
index the pointer to record is being stored

How will you decide which type of index is to be used?


Balanced/B* Tree Index:
These indexes are the standard index type. Typically we use this type of index when we have large set of
unique values

Example:
CREATE INDEX EMP_DEPTID_IX ON HR.EMPLOYEES(DEPARTMENT_ID);

Bitmap Index:
The database stores a bitmap for each index key. In a B-tree index, one index entry points to a single row. In a
bitmap index, each index key stores pointers to multiple rows.
The indexed columns have low cardinality, that is, the number of distinct values is small compared to the
number of table rows.
Example:
CREATE BITMAP INDEX EMPLOYEES_BM_IDX
ON EMPLOYEES (JOBS.JOB_TITLE)
FROM EMPLOYEES, JOBS
WHERE EMPLOYEES.JOB_ID = JOBS.JOB_ID;

Invisible Indexes in Oracle Database 11g:


Oracle 11g allows indexes to be marked as invisible. Invisible indexes are maintained like any other index, but
they are ignored by the optimizer unless the OPTIMIZER_USE_INVISIBLE_INDEXES parameter is set to TRUE at
the instance or session level
CREATE INDEX index_name ON table_name(column_name) INVISIBLE;
ALTER INDEX index_name INVISIBLE;
ALTER INDEX index_name VISIBLE;

17 | P a g e
Created by: Nayan
Invisible indexes can be useful for processes with specific indexing needs, where the presence of the indexes
may adversely affect other functional areas. They are also useful for testing the impact of dropping an index.

Function based Index:


You can create indexes on functions that involve columns in the table being indexed. A function-based
index computes the value of a function involving columns and stores it in the index.

CREATE INDEX EMP_FNAME_UPPERCASE_IDX


ON EMPLOYEES UPPER(FIRST_NAME);

--THE EMP_FNAME_UPPERCASE_IDX INDEX CAN FACILITATE QUERIES SUCH AS THE FOLLOWING:


SELECT * FROM EMPLOYEES WHERE UPPER(FIRST_NAME) = 'AUDREY';
How FBI impacts performance:

18 | P a g e
Created by: Nayan
In above query, to check the condition Optimizer needs to call UPPER function for each and every row of the
table, so we create a FBI on UPPER function so that Optimizer do not need to call the same function again and
again for each record, It can directly access the values from FBI for comparison

Can we create multiple Indexes on Same column?


With oracle 12c this is possible but multiple indexes must be different types like BitMap, B-Tree etc. and one of
them should be INVISIBLE

VIEW:
View is a virtual table that does not physically exist. It is created by a query joining one or more tables.

Advantages/Benefits of using View or why we use View:


To restrict data access
To make complex queries easy
To present different views of same data

Can we create a view if table doesn’t exists? If yes how?


Yes, using FORCE keyword we can create a view even if the table doesn’t exist but that will be in INVALID state,
will get converted to VALID state once the table existed

Materialized View:
A materialized view is a database object that contains the results of a query which is physically stored on the
child servers due to this we will get the result faster as the data is being stored physically on the local/child
servers

Since the MV is stored physically by executing the Complex query (with joins, Group by functions, aggregate
functions etc.), we will get the result faster since the time required for executing complex query will get
minimized

CREATE MATERIALIZED VIEW MV_MY_VIEW


REFRESH FAST START WITH SYSDATE
NEXT SYSDATE + 1
AS SELECT * FROM EMPLOYEES;

Refresh methods of MV:

• FAST: It is the incremental refresh method, which performs the refresh according to the changes that
have occurred to the master tables since the last refresh
• COMPLETE: It is the complete refresh method, which is implemented by executing the given query of
the MV.
• FORCE: Specify FORCE to indicate that when a refresh occurs, Oracle will perform a fast refresh if one is
possible or a complete refresh if fast refresh is not possible.
• ON COMMIT: Specify ON COMMIT to indicate that a fast refresh is to occur whenever the database
commits a transaction that operates on a master table of the materialized view.

QUERY REWRITE Clause:


The QUERY REWRITE clause lets you specify whether the materialized view is eligible to be used for query
rewrite.
19 | P a g e
Created by: Nayan
For example: If you are executing any query on Oracle server which is same as the query specified in the MV, so
if the Query rewrite is enabled then the result will be shown from MV stored on the local server

VIEW vs MVIEW:
In Views query result is not physically stored but MView store query result physically.
In case of View we always get latest data but in case of MView we need to refresh the view for getting latest
data.
View is dynamic while the MView is static

Deterministic Functions:
A deterministic function always returns the same value if the input parameters are identical.
1+1 is always equal to 2 but a function called Get_Customer_Name(4711) won't return the same value because
it fetches data from the database which changes.

Soft parsing Vs Hard Parsing:


Whenever you execute query for the first time in the given session it goes through all the steps like parsing,
binding, executing, fetching etc. which is known as Hard parsing while if you execute the same query in the
same session the query will get executed directly which is known as Soft parsing.

Cursor:
It is a temporary work area which is used to store the row-set into the memory
2 types:
Implicit: DML and Select query returning only one row, is being managed by Oracle server automatically

DECLARE
TOTAL_ROWS NUMBER;
BEGIN
UPDATE EMPLOYEES
SET SALARY = SALARY + 500 WHERE ROWNUM<10;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('NO DATA UPDATED');
ELSIF SQL%FOUND THEN
TOTAL_ROWS := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE( TOTAL_ROWS || ' ROWS UPDATED ');
END IF;
END;

Implicit Cursor Attribute:


SQL%NOTFOUND:
SQL%FOUND:
SQL%ROWCOUNT:

Explicit: Select query returning more than one rows, is user defined and needs to be handle programmatically

DECLARE
V_FN EMPLOYEES.FIRST_NAME%TYPE;
V_LN EMPLOYEES.LAST_NAME%TYPE;
CURSOR C1 IS
20 | P a g e
Created by: Nayan
SELECT E.FIRST_NAME, E.LAST_NAME FROM EMPLOYEES E; --Cursor declaration
BEGIN
OPEN C1; --Opening Cursor
LOOP
FETCH C1
INTO V_FN, V_LN; --Fetching data from cursor and storing into the variable
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('FIRST NAME: ' || V_FN || ' LAST NAME: ' || V_LN);
END LOOP;
CLOSE C1; --Closing cursor
END;

--CURSOR USINF FOR LOOP


DECLARE
CURSOR C1 IS
SELECT E.FIRST_NAME, E.LAST_NAME FROM EMPLOYEES E WHERE ROWNUM<=10;
BEGIN
FOR REC IN C1 LOOP
DBMS_OUTPUT.PUT_LINE('FIRST NAME: ' || REC.FIRST_NAME ||
' LAST NAME: ' || REC.LAST_NAME);
END LOOP;
END;

Explicit Cursor Attribute:


CUR_NAME%NOTFOUND:
CUR_NAME%FOUND:
CUR_NAME%ROWCOUNT:
CUR_NAME%ISOPEN:

REF Cursor:
It is useful to return the query result from Oracle DB to client application
You can use the same cursor for multiple times i.e. you can reopen the cursor for different query
DECLARE
V_FN EMPLOYEES.FIRST_NAME%TYPE;
V_LN EMPLOYEES.LAST_NAME%TYPE;
V_SAL EMPLOYEES.SALARY%TYPE;
V_ID EMPLOYEES.EMPLOYEE_ID%TYPE;
V_RC SYS_REFCURSOR; -- Declaring Ref cursor
BEGIN
OPEN V_RC FOR
SELECT E.FIRST_NAME, E.LAST_NAME FROM EMPLOYEES E; -- Opening cursor with given query
LOOP
FETCH V_RC
INTO V_FN, V_LN; -- Fetching data
EXIT WHEN V_RC%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('FIRST NAME: ' || V_FN || ' LAST NAME: ' || V_LN);
END LOOP;
CLOSE V_RC; --Closing Ref Cursor
DBMS_OUTPUT.PUT_LINE('Reusing the ref cursor for another query');
OPEN V_RC FOR
SELECT E.SALARY, E.EMPLOYEE_ID FROM EMPLOYEES E; -- Reopening cursor for another query
LOOP
FETCH V_RC
INTO V_SAL, V_ID;
EXIT WHEN V_RC%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('SALARY: ' || V_SAL || ' ID: ' || V_ID);
END LOOP;
CLOSE V_RC;
END;

21 | P a g e
Created by: Nayan
Sequence:
Automatically generates unique numbers
Typically used to generate PK values
CREATE SEQUENCE customers_seq
START WITH 10
INCREMENT BY 5
MINVALUE 10
MAXVALUE 100
CACHE 10
NOCYCLE;

SELECT CUSTOMERS_SEQ.NEXTVAL, CUSTOMERS_SEQ.NEXTVAL FROM DUAL;

In 11g, you can assign sequence to variable as well,


DECLARE
V_TEST NUMBER := DEPARTMENTS_SEQ.NEXTVAL;
BEGIN
...
END;
Cache: It pre-allocates given number of values into the memory for better performance, you can also specify
NOCACHE
If you set cache 0 then you’ll get an error, if that case you should use NOCACHE
If you specify CYCLE attribute, then you must need to specify MAXVALUE attribute

How will add a column to a table to identify the row uniquely?


Add column using ALTER
Create a sequence to generate unique values
Then update the newly added column using above sequence
UPDATE T1 SET NEW_COL=NEW_SEQ.NEXTVAL

Sequence as Default Value in Oracle 12c:


Before Oracle 12c we have to assign the variable or column sequence using sequence.nextval, but now we can
use sequence as default value. When new row is added sequence automatically increments and writes the
column. It can be shown an example below:
Create sequence seq_t start with 1 increment 1 nocycle;
Create table t_my_tab (id number default seq_t.nextval primary key)

External table:
It is used to link flat file and the data is being displayed in oracle table format.

SQL Loader:
Is used to load the data from external files to Oracle database
Load data from multiple datafiles during the same load session.
Load data into multiple tables during the same load session.

During the execution of SQL loader, 3 files get created as follows:


Log file: This contains all the log of execution
BAD file: This contains all the invalid data from the input file which are having errors like datatype mismatch,
unidentified character etc.
DISCARD file: This contains all the record which does not satisfies the condition specified in the control file

22 | P a g e
Created by: Nayan
DEMO of Parameter file:
USERID=HR/HR
CONTROL=TEST.ctl
DATA="D:\oracle study\loader\TEST.CSV"
LOG=LOG\TestLOG.log
BAD=BAD\Test_BAD.txt
DISCARD=DISC\Test_DISCARD.txt

Demo of Control file:


-- PURPOSE:
-- VERSION: DATE: AUTHOR: DETAILS:
-- ======== ===== ======= ========
-- 1.0
LOAD DATA
Append
-- Append Or TRUNCATE
INTO TABLE LOAD_BILL
--WHEN (1)< 6
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
trans_id,
products,
state_id,
total,
tax,
net_total
)

Calling SQL Loader:


$sqlldr parafile=test.par

23 | P a g e
Created by: Nayan
Oracle Architecture:

Synonym:
A synonym is an alternative name for DB objects such as tables, views, sequences, stored procedures, and
other database objects.
CREATE PUBLIC SYNONYM EMP
FOR HR.EMPLOYEES;

DB Link:
A database link is a schema object in one database that enables you to access objects on another database.

Partitioning:
This is process of dividing the large tables into the sub tables using specified condition to improve the
performance
Partitioning allows tables to be subdivided into smaller pieces, enabling these database objects to be managed
and accessed at a finer level of granularity.
24 | P a g e
Created by: Nayan
Types:
Range Partitioning: We specify range of values to be partitioned
CREATE TABLE EMPLOYEES
(
EMP_ID VARCHAR2(100),
SALARY NUMBER(10),
)
PARTITION BY RANGE (SALARY)
(
PARTITION P1 VALUES LESS THAN 10000,
PARTITION P2 VALUES LESS THAN 40000,
PARTITION P3 VALUES LESS THAN 100000,
PARTITION P4 VALUES LESS THAN 500000
);

Hash Partitioning: Oracle internally performs hash function to partition the values
CREATE TABLE PURCHASE_ORDER
(
PURCHASE_ORDER_NO NUMBER (10),
PURCHASE_ORDER_TYPE VARCHAR2 (5),
PURCHASE_ORDER_DATE DATE,
FREIGHT_DATE DATE,
FREIGHT_AMOUNT NUMBER (10, 2),
PURCHASE_ORDER_AMOUNT NUMBER (10, 2)
)
PARTITION BY HASH (PURCHASE_ORDER_NO)
PARTITIONS 4;

List Partitioning: We specify list of values based on which the partitioning is done
CREATE TABLE SALES
(
SALES_NO NUMBER,
DEPT_NAME VARCHAR2 (20),
SALE_AMOUNT NUMBER (10, 2),
REGION VARCHAR2 (10)
)
PARTITION BY LIST (REGION)
(
PARTITION P1 VALUES ('NORTH'),

25 | P a g e
Created by: Nayan
PARTITION P2 VALUES ('SOUTH'),
PARTITION P3 VALUES ('EAST'),
PARTITION P4 VALUES ('WEST')
);
Composite Partitioning: It consists combination of any of the above 2 types

How will you decide that which partition is to be used?


It depends on situation, if column name contains DATE then we can partition by Range
If column has numeric value, then we can also partition by RANGE
If the column contains the set of values, then we will use LIST
If we are not sure about the data of the column, then we will go for HASH

*If the performance doesn’t get increased after doing partitioning then we can also add index to the
partitions

Local Partitioned Indexes:


Each partition of a local index is associated with exactly one partition of the table.

In a local index, all keys in a particular index partition refer only to rows stored in a single underlying table
partition. A local index is created by specifying the LOCAL attribute.

Global Partitioned Indexes:


You can create global partitioned indexes on nonpartitioned and partitioned tables. In a global partitioned
index, the keys in index partition may refer to rows stored in multiple underlying table partitions or sub
partitions. A global index can be range or hash partitioned, though it can be defined on any type of partitioned
table.

26 | P a g e
Created by: Nayan
CREATE INDEX cust_id_prod_id_global_ix
ON sales(cust_id,prod_id)
GLOBAL PARTITION BY HASH (cust_id)
( PARTITION p1 TABLESPACE tbs1
, PARTITION p2 TABLESPACE tbs2
, PARTITION p3 TABLESPACE tbs3
, PARTITION p4 TABLESPACE tbs4
)
PARALLEL NOLOGGING;

New Partitioning features in 11g


Extended Composite Partitioning
Up to Oracle 9i, Sub partitioning can done only of type i.e. Range-List and Range-Hash but now it is extended to
any combination as follows,
• Range-range
• Range-hash
• Range-list
• List-range
• List-hash
• List-list

Reference Partitioning
This creates partitions identical to those in the parent table. The clause partition by reference has the name of
the foreign key in the partition definition. This instructs Oracle Database 11g to confirm the partitioning is done
per the scheme used in the parent table.
PARTITION BY REFERENCE (FK_SALES_01);

Reference partitions come extremely handy when you want to partition a child table in the same fashion as in
the parent table but do not have the same columns, and you do not want to introduce them just for the sake of
partitioning. Furthermore, you do not need to explicitly declare a long partitioning clause for each child table.

Interval Partitioning:
What happens if a record is inserted into the table that does not belong to any partition? The insert will fail
with the following error:
ORA-14400: inserted partition key does not map to any partition

27 | P a g e
Created by: Nayan
In 11g, you don't define partitions and their boundaries but merely an interval that defines each partition's
boundaries, Oracle will automatically create new partition on inserting new value based on the given Range.
Here is the same example in interval partitioning:

CREATE TABLE SALES6


(
SALES_ID NUMBER,
SALES_DT DATE
)
PARTITION BY RANGE (SALES_DT)

INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION P0701 VALUES LESS THAN (TO_DATE('2007-02-01','YYYY-MM-DD'))
);

COLLECTIONS:

In normal FOR loop, the loop gets iterated for all the record of the collection which increases the database hits
so to reduce this we use FOR ALL which hits the database only once to perform the operation.

You can write only ONE DML operation in FOR ALL


We should never write END LOOP statement in FOR ALL
If you want to perform multiple DML operation, then you need to write multiple FOR ALL for every DML
statement since FOR ALL allows only one DML to be performed.

SAVE EXCEPTIONS:
You can use this to get the list of exceptions occurred while executing the DML on the Oracle sever using FOR
ALL

BEGIN
FORALL I IN V_EMP.FIRST .. V_EMP.LAST SAVE EXCEPTIONS
INSERT INTO FORALL_TEST VALUES V_EMP(I);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -24381 THEN
FOR INDX IN 1 .. SQL%BULK_EXCEPTIONS.COUNT LOOP
28 | P a g e
Created by: Nayan
DBMS_OUTPUT.PUT_LINE(SQL%BULK_EXCEPTIONS(INDX).ERROR_INDEX || ‘
:‘ || SQL%BULK_EXCEPTIONS(INDX).ERROR_CODE);
END LOOP;
ELSE
RAISE;
END IF;
END;

How can I combine multiple rows into a comma-delimited list in Oracle?


SELECT DEPARTMENT_ID, LISTAGG(EMPLOYEE_ID, ',') WITHIN GROUP (ORDER BY EMPLOYEE_ID)
AS EMPLOYEES FROM EMPLOYEES
GROUP BY DEPARTMENT_ID;

DEPARTMENT_ID EMPLOYEES
------------- ---------------------------------------
10 200
20 201,202
30 114,115,116,117,118,119
40 203
50 120,121,122,123,124,125,126,127,128,129

Splitting string into multiple rows in Oracle


SELECT DISTINCT ID, TRIM(REGEXP_SUBSTR(VALUE,'[^,]+', 1, LEVEL) ) VALUE, LEVEL
FROM TBL1
CONNECT BY REGEXP_SUBSTR(VALUE, '[^,]+', 1, LEVEL) IS NOT NULL
ORDER BY ID, LEVEL;
OR
SELECT TRIM(REGEXP_SUBSTR('ERR1, ERR2, ERR3', '[^,]+', 1, LEVEL)) STR_2_TAB
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT('ERR1, ERR2, ERR3', ',')+1

Table Functions:
Table functions are used to return PL/SQL collections. They can be queried like a regular table by using the
TABLE function in the FROM clause. Regular table functions require collections to be fully populated before
they are returned.
Since collections are held in memory, this can be a problem as large collections can waste a lot of memory and
take a long time to return the first row. Regular table functions require named row and table types to be
created as database objects.

CREATE TYPE t_tf_row AS OBJECT (


id NUMBER,
description VARCHAR2(50)
);
CREATE TYPE t_tf_tab IS TABLE OF t_tf_row;
-- Build the table function itself.
CREATE OR REPLACE FUNCTION get_tab_tf (p_rows IN NUMBER) RETURN t_tf_tab AS
l_tab t_tf_tab := t_tf_tab();
BEGIN
FOR i IN 1 .. p_rows LOOP
l_tab.extend;
l_tab(l_tab.last) := t_tf_row(i, 'Description for ' || i);
END LOOP;
RETURN l_tab;
END;
Can be invoked as,
SELECT * FROM TABLE(get_tab_tf(10));
29 | P a g e
Created by: Nayan
Pipelined Table Functions:
Pipelining negates the need to build huge collections by piping rows out of the function as they are created,
saving memory and allowing subsequent processing to start before all the rows are generated.

Pipelined table functions include the PIPELINED clause and use the PIPE ROW call to push rows out of the
function as soon as they are created, rather than building up a table collection. Notice the empty RETURN call,
since there is no collection to return from the function.
-- Build a pipelined table function.
CREATE OR REPLACE FUNCTION get_tab_ptf (p_rows IN NUMBER) RETURN t_tf_tab PIPELINED AS
BEGIN
FOR i IN 1 .. p_rows LOOP
PIPE ROW(t_tf_row(i, 'Description for ' || i));
END LOOP;
RETURN;
END;
/
-- Test it.
SELECT * FROM TABLE(get_tab_ptf(10)) ORDER BY id DESC;

Bind Variable:

NO COPY:

For update and No wait:

On delete cascade:

On Delete set null:

Oracle 12g features for developers:


Varchar2 Length to 32,767 Bytes
The maximum size of the VARCHAR2, NVARCHAR2, and RAW data types has been increased from 4,000 to 32,767 bytes.
Invisible columns:
We can define column as invisible, it won’t get displayed when we execute “Select * from” command. We need to specify
column name to query the invisible column. This feature is useful especially when we don’t need that column instead of
drop it for some security reasons, for example password column etc.
ALTER TABLE EMP MODIFY (pwd invisible);

Identity Columns
With Oracle 12c we can define a column as identity column. When new row is added sequence automatically increments
and writes the column.
CREATE TABLE T_MY_TAB
(
USER_ID NUMBER GENERATED AS IDENTITY
);

Top-N Feature
With Oracle 12c new keywords came out for Top-N queries
SELECT value FROM EMP ORDER BY value DESC FETCH FIRST 10 ROWS ONLY;
With Clause
We can use pl/sql in select query using new with clause
WITH
FUNCTION f_incr(n IN NUMBER) RETURN NUMBER IS

30 | P a g e
Created by: Nayan
BEGIN
RETURN n+1;
END;
SELECT f_incr(1)
FROM dual;

How do I get all dates from sysdate's month with Oracle SQL?

SELECT TRUNC(SYSDATE, 'MM') + LEVEL - 1 AS DAY


FROM DUAL
CONNECT BY LEVEL <= EXTRACT(DAY FROM LAST_DAY(SYSDATE))

Search use of table in various procs


SELECT * FROM ALL_SOURCE WHERE TEXT LIKE '%JOB_HISTORY%'

Oracle SQL select max value from multiple columns

NAME M1 M2 M3 M4
---- ---------- ---------- ---------- ----------
A 1 2 3 4
B 6 3 4 5
C 1 5 2 1

SELECT NAME, GREATEST(M1,M2,M3,M4) FROM YOUR_TABLE

Vice-versa:
SELECT NAME, LEAST(M1,M2,M3,M4) FROM YOUR_TABLE

How to check any missing number i.e. Gaps from a series of numbers or sequence?
select x, next_x
from (select x, lead(x) over(order by x) next_x from t)
where x <> next_x – 1

To get actual missing values:


select min_a - 1 + level
from ( select min(a) min_a
, max(a) max_a
from test1
)
connect by level <= max_a - min_a + 1
minus
select a
from test1

Analytical function:
Analytic functions also operate on subsets of rows, like aggregate functions in GROUP BY queries, but they do not reduce
the number of rows returned by the query.

SELECT e.*,
AVG(e.salary) OVER(PARTITION BY e.department_id) AS avg_dept_sal
FROM Employees e;

31 | P a g e
Created by: Nayan
SELECT e.*,
ROW_NUMBER() OVER(ORDER BY e.salary) AS row_num,
RANK() OVER(ORDER BY e.salary) AS row_rank,
DENSE_RANK() OVER(ORDER BY e.salary) AS row_dense_rank
FROM Employees e;

Query to join table at runtime based on column values in oracle

ACTION_ITEMS
-------
ID SOURCE_ID SOURCE_TYPE
1 12345 INC
2 67890 AUD

INCIDENTS
-------
ID
12345

AUDITS
-------
ID
67890

SELECT AI.*
FROM ACTION_ITEMS AI
LEFT JOIN INCIDENTS ON AI.SOURCE_TYPE = 'INC' AND (AI.SOURCE_ID = INCIDENTS.ID)
LEFT JOIN AUDITS ON AI.SOURCE_TYPE = 'AUD' AND (AI.SOURCE_ID = INCIDENTS.ID)

How to find details of long running query:

SELECT sid,
to_char(start_time, 'hh24:mi:ss') stime,
message,
(sofar / totalwork) * 100 percent
FROM v$session_longops
WHERE sofar / totalwork < 1

Mutating Table error:

Purge statement:
Use the PURGE statement to remove the entire recycle bin

When issuing a DROP TABLE statement in Oracle, you can specify the PURGE option. The PURGE option will purge the
table and its dependent objects so that they do not appear in the recycle bin. The risk of specifying the PURGE option is
that you will not be able to recover the table. However, the benefit of using PURGE is that you can ensure that sensitive
data will not be left sitting in the recycle bin.

Key compression index:


Both non-unique and unique indexes can have their key elements compressed to save space. The COMPRESS [N] clause
indicates compression is required, with "N" optionally specifying the prefix, or number of keys to compress. The default
for index creation is NOCOMPRESS.

32 | P a g e
Created by: Nayan
Reverse key index:
Reverse key indexes literally reverse the bytes of the key value in the index to reduce block contention on sequence
generated primary keys.

A Reverse Key Index simply takes the index column values and reverses them before inserting into the index.
“Conceptually”, say the next generated ID is 123456, Oracle will reverse it to 654321 before inserting into the index. It
will then take the next generated ID 123457 and reverse it to 754321 and insert it into the index and so on. By doing this,
inserts are spread across the whole index structure, ensuring the right most block is no longer the only index leaf block
being hammered. Index contention is dramatically reduced or eliminated entirely.

Online redo log:


The most crucial structure for recovery operations is the online redo log, which consists of two or more preallocated files
that store all changes made to the database as they occur. Every instance of an Oracle database has an associated online
redo log to protect the database in case of an instance failure.

Full table scan problem:


Whenever we fetch more than 80% of table data from the indexed column, oracle does full table scan instead of index
scan as it is faster than index range scan.

Is it possible to create PK without creating index?


You can't create a primary key without the corresponding index being created. A primary key under the covers will use
either a UNIQUE or NON-UNIQUE index. If the primary key is deferrable it'll use a non-unique index. If the column(s) are
already indexed with a non-unique index, the primary key constraint will rely on that index. Otherwise a primary key will
happen to create a unique index.

The index, itself, does not enforce the uniqueness. The constraint does, and the constraint makes use of an index (be it a
UNIQUE index or an index that allows for duplicates) to make this enforcement go faster.

33 | P a g e
Created by: Nayan

You might also like