PL SQL
PL SQL
2. NAMED BLOCKS
ANONYMOUS BLOCK
NAMED BLOCK
|
|
----------------------------------------------------
| |
|
| |
|
DECLARATION SECTION |
EXCEPTION HANDLING SECTION
|
EXECUTION
SECTION
BEGIN
---- EXECUTABLE
STATEMENTS
EXCEPTIONS
---- EXCEPTION
HANDLING STATEMENTS
END;
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE(MYVAR);
END;
SQL> DECLARE
MYVAR1 VARCHAR2(20);
BEGIN
MYVAR1:='KARTHIK KONANKI';
DBMS_OUTPUT.PUT_LINE(MYVAR1);
END;
SQL> DECLARE
V_NAME VARCHAR2(15);
BEGIN
V_NAME := 'KARTHIK';
DBMS_OUTPUT.PUT_LINE(V_NAME);
END;
SQL> DECLARE
V_SALARY NUMBER(8);
BEGIN
SELECT SAL INTO V_SALARY FROM EMP
WHERE EMPNO=7654;
DBMS_OUTPUT.PUT_LINE(V_SALARY);
END;
/
SQL> DECLARE
V_SALARY NUMBER(8);
V_NAME VARCHAR2(15);
BEGIN
SELECT SAL, ENAME INTO V_SALARY,
V_NAME FROM EMP
WHERE EMPNO=7654;
DBMS_OUTPUT.PUT_LINE(V_SALARY ||' IS
THE SALARY OF '||V_NAME);
END;
/
SQL> DECLARE
V_NAME EMP.ENAME%TYPE
BEGIN
END;
/
SQL> DECLARE
VNAME VARCHAR2(15);
BEGIN
SELECT ENAME INTO VNAME FROM EMP WHERE
EMPNO=7654;
DBMS_OUTPUT.PUT_LINE(VNAME);
END;
/
CONSTANTS IN PL/SQL:
SYNTAX: CONSTANT_NAME
CONSTANT DATATYPE(DW):= VALUE;
SQL> DECLARE
V_PI CONSTANT NUMBER(7,6):=3.141592;
BEGIN
DBMS_OUTPUT.PUT_LINE(V_PI);
END;
SQL> DECLARE
V_PI CONSTANT NUMBER(7,6);
BEGIN
V_PI:= 3.141592
DBMS_OUTPUT.PUT_LINE(V_PI_1);
END;
--> ERROR
SQL> DECLARE
V_PI CONSTANT NUMBER(7,6) DEFAULT
3.141592;
BEGIN
DBMS_OUTPUT.PUT_LINE(V_PI);
END;
SQL> DECLARE
V_PI CONSTANT NUMBER(7,6) NOT NULL
DEFAULT 3.141592;
BEGIN
DBMS_OUTPUT.PUT_LINE(V_PI);
END;
BIND VARIABLES | HOST VARIABLES:
SQL> BEGIN
:V_BIND := 'KARTHIK';
END;
/
SQL> BEGIN
:V_BIND := 'KARTHIK';
DBMS_OUTPUT.PUT_LINE(:V_BIND);
END;
/
CONTROL STATEMENTS:
IF THEN ELSE
IF THEN ELSEIF
2. CASE
STATMENT: SIMPLE CASE
SEARCHED CASE
IF-THEN STATEMENT:
SQL> DECLARE
V_NUM NUMBER :=9;
BEGIN
IF V_NUM < 10 THEN
DBMS_OUTPUT.PUT_LINE('INDISE THE
IF');
END IF;
DBMS_OUTPUT.PUT_LINE('OUTSIDE THE
IF');
END;
/
SQL> DECLARE
V_WEB VARCHAR2(30) :=
'KARTHIK_KONANKI.COM';
V_AUTHOR VARCHAR(20) := 'KARTHIK
KONANKI';
BEGIN
IF V_WEB = 'KARTHIK_KONANKI.COM' AND
V_AUTHOR = 'KONANKI KARTHIK' THEN
DBMS_OUTPUT.PUT_LINE('EVERYTHING IS
AWESOME');
END IF;
DBMS_OUTPUT.PUT_LINE('GIVE THIS
VIDEO THUMBS UP');
END;
/
SQL> DECLARE
V_NUM NUMBER :=
&ENTER_A_NUMBER;
BEGIN
IF MOD(V_NUM, 2)=0
THEN
SQL> DECLARE
V_PLACE
VARCHAR2(30):='&ENTER_PLACE';
BEGIN
IF V_PLACE =
'METROPOLIS' THEN
2. WHILE LOOP
3. NUMERIC FOR
LOOP
4. CURSOR FOR
LOOP
SIMPLE LOOP:
2. EXIT WHEN
SQL> LOOP
STATEMENT 1;
STATEMENT 2;
...
STATEMENT N;
END LOOP;
-- EXIT
SQL> DECLARE
V_COUNTER NUMBER :=
0;
V_RESULT NUMBER;
BEGIN
LOOP
V_COUNTER:=V_COUNTER + 1;
V_RESULT:= 19 *
V_COUNTER;
-- EXIT WHEN
SQL> DECLARE
V_COUNTER NUMBER :=
0;
V_RESULT NUMBER;
BEGIN
LOOP
V_COUNTER:=V_COUNTER + 1;
V_RESULT:= 19 *
V_COUNTER;
SQL> DECLARE
V_COUNTER NUMBER :=
0;
V_RESULT NUMBER;
BEGIN
WHILE V_COUNTER <=
10 LOOP
V_RESULT:= 19 *
V_COUNTER;
V_COUNTER:=V_COUNTER + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('OUTSIDE THE
LOOP');
END;
/
SQL> DECLARE
V_TEST BOOLEAN := TRUE;
V_COUNTER NUMBER := 0;
BEGIN
WHILE V_TEST LOOP
V_COUNTER := V_COUNTER + 1;
DBMS_OUTPUT.PUT_LINE(V_COUNTER);
IF V_COUNTER = 10 THEN
V_TEST := FALSE;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('OUTSIDE THE
LOOP');
END;
/
TYPES: 1. NUMERIC
FOR LOOP
2. CURSOR
FOR LOOP
SQL> BEGIN
FOR V_COUNTER IN 1 ..
10 LOOP
DBMS_OUTPUT.PUT_LINE(V_COUNTER);
END LOOP;
END;
SQL> BEGIN
FOR V_COUNTER IN REVERSE 1 .. 10 LOOP
DBMS_OUTPUT.PUT_LINE(V_COUNTER);
END LOOP;
END;
SQL> DECLARE
V_RESULT NUMBER;
BEGIN
FOR V_COUNTER IN 1 ..
10 LOOP
V_RESULT := 19 * V_COUNTER;
DBMS_OUTPUT.PUT_LINE('19'||' X '||
V_COUNTER||' = '||V_RESULT);
END LOOP;
END;
TRIGGERS:
--> NAMED PL/SQL BLOCKS WHICH ARE STORED IN
THE DATABASE
TYPES OF TRIGGERS:
-- DML TRIGGERS
-- DDL TRIGGERS
-- SYSTEM/DB EVENT TRIGGERS
-- INSTEAD-OF TRIGGERS
-- COMPOUND TRIGGERS
1. DML TRIGGERS:
--- AUDITING
2. DDL TRIGGERS:
3. DATABASE EVENT:
4. INSTEAD-OF TRIGGERS
CURSORS IN PL\SQL:
1. IMPLICIT CURSOR: --
AUTOMATICALLY CREATED BY THE ORACLE SERVER
-- USER CANNOT
CONTROL THE BEHAVIOUR OF THESE CURSORS
--
ORACLE SERVER CREATES AN IMPLICIT CURSOR FOR ANY PL/SQL BLOCK WHICH AN SQL
STATEMENT
-- AS
LONG AS AN EXPLICT CURSOR DOESNOT EXIST FOR THAT SQL STATEMENT
2. EXPLICIT CURSOR: -- EXPILICT
CURSORS ARE USER DEFINED CURSORS
-- USER HAS
FULL CONTROL OF EXPLICIT CURSOR
----------------------------------------------------
| |
| |
|
| | |
|
| | |
DECLARE
| | |
| | |
| | |
OPEN | |
| |
| |
FETCH |
CLOSE
SQL> DECLARE
V_NAME VARCHAR2(30);
CURSOR CUR_SCOTT IS
SELECT FIRST_NAME FROM EMPLOYEES
WHERE EMPLOYEE_ID < 105;
BEGIN
OPEN CUR_SCOTT
LOOP
FETCH CUR_SCOTT INTO V_NAME;
DBMS_OUTPUT.PUT_LINE(V_NAME);
EXIT WHEN CUR_SCOTT%NOTFOUND;
END LOOP;
CLOSE CUR_SCOTT;
END;
SQL> DECLARE
V_NAME VARCHAR2(30);
CURSOR P_CUR_SCOTT (VAR_E_ID VARCHAR2) IS
SELECT FIRST_NAME FROM EMPLOYEES
WHERE EMPLOYEE_ID < VAR_E_ID;
BEGIN
OPEN P_CUR_SCOTT(105);
LOOP
FETCH P_CUR_SCOTT INTO V_NAME;
EXIT WHEN P_CUR_SCOTT%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(V_NAME);
END LOOP;
CLOSE P_CUR_SCOTT;
END;
/
SQL> DECLARE
V_NAME VARCHAR2(30);
V_EID NUMBER(10);
CURSOR CUR_SCOTT(VAR_ID NUMBER := 190) IS
SELECT FIRST_NAME, EMPLOYEE_ID FROM
EMPLOYEES
WHERE EMPLOYEE_ID > VAR_ID;
BEGIN
OPEN CUR_SCOTT;
LOOP
FETCH CUR_SCOTT INTO V_NAME, V_EID;
EXIT WHEN CUR_SCOTT%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(V_NAME||' '||
V_EID);
END LOOP;
END;
/
--- CURSOR FOR LOOP
SQL> DECLARE
CURSOR CUR_SCOTT IS
SELECT FIRST_NAME, LAST_NAME FROM
EMPLOYEES
WHERE EMPLOYEE_ID > 200;
BEGIN
FOR L_IDX IN CUR_SCOTT
LOOP
DBMS_OUTPUT.PUT_LINE(L_IDX.FIRST_NAME||' '||L_IDX.LAST_NAME);
END LOOP;
END;
/
SQL> DECLARE
CURSOR CUR_SCOTT(VAR_ID NUMBER) IS
SELECT FIRST_NAME, LAST_NAME FROM
EMPLOYEES
WHERE EMPLOYEE_ID > (VAR_ID);
BEGIN
FOR L_IDX IN CUR_SCOTT
LOOP
DBMS_OUTPUT.PUT_LINE(L_IDX.FIRST_NAME||' '||L_IDX.LAST_NAME);
END LOOP;
END;
/
SQL> DECLARE
V_FNAME VARCHAR2(20);
V_SALARY VARCHAR2(8);
BEGIN
SELECT FIRST_NAME,
SALARY INTO V_FNAME, V_SALARY
FROM EMPLOYEES WHERE
EMPLOYEE_ID = 200;
DBMS_OUTPUT.PUT_LINE(V_FNAME||' '||V_SALARY);
END;
/
SQL> DECLARE
V_EMP EMPLOYEES%ROWTYPE;
BEGIN
SELECT * INTO V_EMP
FROM EMPLOYEES WHERE EMPLOYEE_ID = 200;
DBMS_OUTPUT.PUT_LINE(V_EMP.FIRST_NAME||' '||V_EMP.SALARY);
END;
/
SQL> DECLARE
V_EMP EMPLOYEES%ROWTYPE;
BEGIN
SELECT FIRST_NAME INTO V_EMP.FIRST_NAME
FROM EMPLOYEES WHERE EMPLOYEE_ID = 200;
DBMS_OUTPUT.PUT_LINE(V_EMP.FIRST_NAME);
END;
/
SQL> DECLARE
V_EMP EMPLOYEES%ROWTYPE;
BEGIN
SELECT FIRST_NAME, SALARY INTO
V_EMP.FIRST_NAME, V_EMP.SALARY
FROM EMPLOYEES WHERE EMPLOYEE_ID = 200;
DBMS_OUTPUT.PUT_LINE(V_EMP.FIRST_NAME||'
'||V_EMP.SALARY);
END;
/
SQL> DECLARE
CURSOR CUR_SCOTT IS
SELECT FIRST_NAME, SALARY FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
V_EMP CUR_SCOTT%ROWTYPE;
BEGIN
OPEN CUR_SCOTT;
FETCH CUR_SCOTT INTO V_EMP;
DBMS_OUTPUT.PUT_LINE(V_EMP.FIRST_NAME||'
'||V_EMP.SALARY);
CLOSE CUR_SCOTT;
END;
/
SQL> DECLARE
CURSOR CUR_HR IS
SELECT FIRST_NAME, SALARY FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
--cursor based record variable declare
V_EMP CUR_HR%ROWTYPE;
V_CUR V_EMP%TYPE;
BEGIN
OPEN CUR_HR;
FETCH CUR_HR INTO V_CUR;
DBMS_OUTPUT.PUT_LINE (V_CUR.FIRST_NAME);
DBMS_OUTPUT.PUT_LINE (V_CUR.SALARY);
CLOSE CUR_HR;
END;
/
SQL> DECLARE
CURSOR CUR_HR IS
SELECT FIRST_NAME,
SALARY FROM EMPLOYEES
WHERE EMPLOYEE_ID >
200;
V_EMP CUR_HR%ROWTYPE;
BEGIN
OPEN CUR_HR;
LOOP
FETCH CUR_HR INTO
V_EMP;
EXIT WHEN CUR_HR
%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(V_EMP.FIRST_NAME||' '||V_EMP.SALARY);
END LOOP;
CLOSE CUR_HR;
END;
/
--- CAN WE SIMPLIFY THIS CODE?
RECORD_NAME TYPE_NAME;
SQL> DECLARE
TYPE RV_DEPT IS RECORD
(
F_NAME VARCHAR2(20),
D_NAME DEPARTMENTS.DEPARTMENT_NAME%TYPE
);
VAR1 RV_DEPT;
BEGIN
SELECT FIRST_NAME, DEPARTMENT_NAME INTO
VAR1.F_NAME, VAR1.D_NAME
FROM EMPLOYEES JOIN DEPARTMENTS USING
(DEPARTMENT_ID) WHERE EMPLOYEE_ID = 100;
DBMS_OUTPUT.PUT_LINE(VAR1.F_NAME||' '||
VAR1.D_NAME);
END;
/
PL/SQL FUNCTIONS:
TYPES OF SUBROUTINES OR
SUB-PROGRAMS
1. PL/SQL FUNCTIONS
2. PL/SQL PROCEDURES
SQL>
-- A STORED PROCEDURE IS
A SELF CONTAINED SUB-PROGRAM THAT IS MEANT TO DO SOME SPECIFIC TASKS
-- VALUE RETURN BY
PROCEDURE CANNOT BE ASSIGN TO A VARIABLE
SQL> BEGIN
PR_HR;
END;
/
-- WRITE A STORED PROCEDURE AND TRY
CALLING IT USING A NAMED PL/SQL BLOCK SUCH AS PL\SQL FUNCTION OR TRIGGER
--- PARAMETERS
1. POSITIONAL NOTATION: IN
POSITIONAL NOTATION YOU HAVE TO SPECIFY THE VALUE FOR EACH FORMAL PARAMETER IN A
SEQUENTIAL MANNER
FORMAL
PARAMETER => VALUE
PL/SQL PACKAGES:
-- STORED LIBRARIES IN THE DATABASE WHICH
ALLOWS US TO GROUP RELATED PL/SQL OBJECTS UNDER ONE NAME
-- PACKAGES ARE LOGICAL GROUPS OF RELATED
PL/SQL OBJECTS
-- PACKAGES ARE NAMED PL/SQL BLOCKS
-- PERMINENTLY STORED INTO THE DATABASE
SCHEMA
-- CAN BE REFERENCED OR REUSED BY PROGRAM
-- IT CAN INCLUDE STORED PROCEDURES, PL/SQL
FUNCTIONS, DATABASE CURSORS, TYPE DECLARATION
SQL> BEGIN
DBMS_OUTPUT.PUT_LINE(PACKAGE_HR.PRNT_STRING);
END;
SQL> BEGIN
PACKAGE_HR.P_SUPERHERO('BLACK', 'WIDOW');
END;
TYPES OF EXCEPTIONS:
1. SYSTEM DEFINED EXCEPTIONS
2. USER DEFINED EXCEPTIONS
1. SYSTEM DEFINED EXCEPTIONS: -- DEFINED AND
MAINTAINED INPLICITLY BY THE ORACLE SERVER
-- THESE ARE MAINLY
DEFINED IN THE ORACLE STANDARD PACKAGE
-- WHENEVER AN
EXCEPTIION OCCUR INSIDE THE PROGRAM, ORCALE SERVER MATCHES AND IDENTIFIES THE
APPROPRIATE
EXCEPTION FROM THE AVAILABLE SET OF EXCEPTIONS FROM ORACLE STANDARD PACKAGE
SQL> DECLARE
VAR_DIVIDEND NUMBER := 24;
VAR_DIVISOR NUMBER := 0;
VAR_RESULT NUMBER;
EX_DIVZERO EXCEPTION;
BEGIN
IF VAR_DIVISOR = 0 THEN
RAISE EX_DIVZERO;
END IF;
VAR_RESULT :=
VAR_DIVIDEND/VAR_DIVISOR;
DBMS_OUTPUT.PUT_LINE('RESULT = '||
VAR_RESULT);
EXCEPTION WHEN EX_DIVZERO THEN
DBMS_OUTPUT.PUT_LINE('ERROR ERROR! -
YOUR DIVISOR IS ZERO');
END;
/
2. USING RAISE_APPLICATION_ERROR
METHOD:
-- THIS
METHOD IS A PROCEDURE WHICH COMES IN-BUILT WITH ORACLE SOFTWARE
-- USING THIS PROCEDURE YOU CAN ASSSOCIATE AN ERROR NUMBER WITH THE CUSTOM
ERROR MESSAGE
-- COMBINING BOTH THE ERROR NUMBER AND CUSTOM ERROR MESSAGE YOU CAN COMPOSE
AN ERROR STRING
WHICH LOOK SIMILAR
TO THOSE DEFAULT ERROR STRINGS WHICH ARE DISPLAYED BY ORACLE ENGINE
WHEN ERROR OCCURS
DECLARE
AGE NUMBER := &VAR_AGE;
BEGIN
IF AGE < 18 THEN
RAISE_APPLICATION_ERROR(-20008, 'You
should be 18 or above for the drinks!'); --NUMBER SHOULD BE -20000 TO -20999
END IF;
DBMS_OUTPUT.PUT_LINE('Sure, What
would you like to have?');
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
COLLECTIONS IN PL/SQL:
-- A HOMOGENEOUS SINGLE DIMENSION
DATA STRUCTURE WHICH IS MADE OF ELEMENTS OF SAME DATATYPE IS
CALLED COLLECTION IN ORACLE
DATABASE
-- AN ARRAY IN ORACLE DATABASE
2. NON PERSISTANT
-- NON-PERSISTANT COLLECTION ONLY STORES DATA AND STRUCTURE JUST FOR ONE SESSION
A. ASSOCIATIVE
TYPE
NESTED_TABLE_NAME IS TABLE OF ELEMENT_TYPE[NOT NULL];
SQL> DECLARE
TYPE NEST_TABLE IS TABLE
OF NUMBER;
VAR_NT NEST_TABLE :=
NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
FOR I IN 1..VAR_NT.COUNT
LOOP
-- UNLIKE NESTED TABLE WHICH REQUIRES AN EXTERNAL TABLE FOR ITS STOREAGE
-- VARRAYs ARE STORED IN-LINE WITH THEIR PARENT RECORDS AS RAW VALUE IN THE PARENT
TABLE
SQL> DECLARE
TYPE INBLOCK_VRY IS VARRAY(5) OF NUMBER;
VRY_OBJ INBLOCK_VRY := INBLOCK_VRY(NULL,
NULL, NULL, NULL, NULL);
BEGIN
FOR I IN 1..VRY_OBJ.LIMIT
LOOP
VRY_OBJ(I) := 10*I;
DBMS_OUTPUT.PUT_LINE(VRY_OBJ(I));
END LOOP;
END;
/
SQL> DECLARE
TYPE INBLOCK_VRY IS VARRAY(5) OF NUMBER;
VRY_OBJ INBLOCK_VRY := INBLOCK_VRY();
BEGIN
VRY_OBJ.EXTEND(5);
FOR I IN 1..VRY_OBJ.LIMIT
LOOP
VRY_OBJ(I) := 10*I;
DBMS_OUTPUT.PUT_LINE(VRY_OBJ(I));
END LOOP;
END;
/
SQL> DECLARE
TYPE INBLOCK_VRY IS VARRAY(5) OF NUMBER;
VRY_OBJ INBLOCK_VRY := INBLOCK_VRY();
BEGIN
FOR I IN 1..VRY_OBJ.LIMIT
LOOP
VRY_OBJ.EXTEND;
VRY_OBJ(I) := 10*I;
DBMS_OUTPUT.PUT_LINE(VRY_OBJ(I));
END LOOP;
END;
/
1. ASSSOCIATED ARRAY:
-- NON-
PERSISTENT
DECLARE
TYPE BOOKS IS TABLE OF NUMBER
INDEX BY VARCHAR2(20);
ISBN BOOKS;
BEGIN
ISBN('ORACLE DATABASE') := 1234;
ISBN('MYSQL') := 9876;
ISBN('MUSQL') := 1010;
DBMS_OUTPUT.PUT_LINE('VALUE '||
ISBN('ORACLE DATABASE'));
END;
/
SQL> SET SERVEROUTPUT ON;
SQL> DECLARE
TYPE BOOKS IS TABLE OF NUMBER
INDEX BY VARCHAR2(20);
ISBN BOOKS;
FLAG VARCHAR2(20);
BEGIN
ISBN('ORACLE DATABASE') := 1234;
ISBN('MYSQL') := 9876;
ISBN('MYSQL') := 1010;
FLAG := ISBN.FIRST;
WHILE FLAG IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE('KEY -> '||
FLAG||' VALUE -> '||ISBN(FLAG));
FLAG := ISBN.NEXT(FLAG);
END LOOP;
END;
/
COLLECTION METHODS:
-- COLLECTION METHODS ARE PL/SQL'S
BUILT-IN FUNCTIONS AND PROCEDURES WHICH CAN BE USED IN CONJUNCTION
WITH COLLECTION
-- USING PL/SQL COLLECTION METHOD YOU
CAN GET THE INFORMATION AS WELL AS ALTER THE CONTENT OF THE COLLECTION
-- IN ORACLE DATABASE WE HAVE 3
COLLECTION PROCEDURES AND 7 COLLECTION FUNCTIONS. IN TOTAL WE HAVE 10
COLLECTION METHODS
-- FUNCTIONS: 1. COUNT
2. EXISTS
3. FIRST, LAST
4. LIMIT
5. PRIOR, NEXT
-- PROCEDURES: 1. DELETE
2. EXTEND
3. TRIM
SYNTAX:
COLLECTION.METHOD(PARAMETERS)
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF NUMBER;
VAR_NT MY_NEST_TABLE := MY_NEST_TABLE(9,
18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
IF VAR_NT.COUNT >= 10 THEN
DBMS_OUTPUT.PUT_LINE('YOU ARE ALREADY
INSERTED 10 ELEMENTS');
DBMS_OUTPUT.PUT_LINE('ARE YOU SURE YOU
WANT TO INSERT MORE?');
END IF;
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF NUMBER;
VAR_NT MY_NEST_TABLE := MY_NEST_TABLE(9,
18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
FOR I IN 1..VAR_NT.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('VALUE STORED AT
INDEX '||I||' IS '||VAR_NT(I));
END LOOP;
END;
/
SQL> DECLARE
TYPE MY_NESTED_TABLE IS TABLE OF
VARCHAR2(20);
COL_VAR1 MY_NESTED_TABLE :=
MY_NESTED_TABLE('SUPERMAN', 'IRONMAN', 'BATMAN');
BEGIN
IF COL_VAR1.EXISTS(1) THEN
DBMS_OUTPUT.PUT_LINE('HEY! WE FOUND
'||COL_VAR1(1));
ELSE
DBMS_OUTPUT.PUT_LINE('SORRY! NO DATA
AT THIS INDEX');
END IF;
END;
/
SQL> DECLARE
TYPE MY_NESTED_TABLE IS TABLE OF
VARCHAR2(20);
COL_VAR1 MY_NESTED_TABLE :=
MY_NESTED_TABLE('SUPERMAN', 'IRONMAN', 'BATMAN');
BEGIN
IF COL_VAR1.EXISTS(4) THEN
DBMS_OUTPUT.PUT_LINE('HEY! WE FOUND
'||COL_VAR1(4));
ELSE
DBMS_OUTPUT.PUT_LINE('THIS INDEX IS
EMPTY. INSERTING NEW DATA....');
COL_VAR1.EXTEND;
COL_VAR1(4):= 'SPIDERMAN';
END IF;
DBMS_OUTPUT.PUT_LINE('NEW DATA AT
INDEX 4 IS '||COL_VAR1(4));
END;
/
IN COLLECTION
--
YOU CAN USE BOTH THESE FUNCTIONS WITH ALL THREE TYPES OF COLLECTIONS
--
BOTH THE FUNCTIONS RETURN NULL WHEN APPLIED TO AN EMPTY COLLECTION
--
THEY RAISE COLLECTION_IS NULL EXCEPTION WHEN APPLIED TO AN UNINITIALIZED COLLECTION
SQL> DECLARE
TYPE NT_TAB IS TABLE OF NUMBER;
COL_VAR NT_TAB := NT_TAB(10, 20, 30,
40, 50);
BEGIN
DBMS_OUTPUT.PUT_LINE('FIRST INDEX OF
THE NESTED TABLE IS '||COL_VAR.FIRST);
DBMS_OUTPUT.PUT_LINE('LAST INDEX OF
THE NESTED TABLE IS '||COL_VAR.LAST);
END;
/
SQL> DECLARE
TYPE NT_TAB IS TABLE OF NUMBER;
COL_VAR NT_TAB := NT_TAB(10, 20, 30,
40, 50);
BEGIN
COL_VAR.DELETE(1);
DBMS_OUTPUT.PUT_LINE('FIRST INDEX OF
THE NESTED TABLE IS '||COL_VAR.FIRST);
END;
/
SQL> DECLARE
TYPE NT_TAB IS TABLE OF NUMBER;
COL_VAR NT_TAB := NT_TAB(10, 20, 30,
40, 50);
BEGIN
COL_VAR.TRIM;
DBMS_OUTPUT.PUT_LINE('LAST INDEX
AFTER TRIM '||COL_VAR.FIRST);
END;
/
SQL> DECLARE
TYPE NT_TAB IS TABLE OF NUMBER;
COL_VAR NT_TAB := NT_TAB(10, 20, 30,
40, 50);
BEGIN
COL_VAR.TRIM;
DBMS_OUTPUT.PUT_LINE('LAST INDEX AFTER
TRIM IS '||COL_VAR.LAST);
END;
/
SQL> DECLARE
TYPE INBLOCK_VRY IS VARRAY (5) OF
NUMBER;
VRY_OBJ INBLOCK_VRY :=
INBLOCK_VRY();
BEGIN
-- Let's find out total number of
indexes in the above VARRAY
DBMS_OUTPUT.PUT_LINE('TOTAL INDEXES
'||VRY_OBJ.LIMIT);
END;
/
DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
DBMS_OUTPUT.PUT_LINE('RESULT OF LIMIT
'||VAR_NT.LIMIT);
DBMS_OUTPUT.PUT_LINE('RESULT OF COUNT
'||VAR_NT.COUNT);
END;
/
LOWEST INDEX
-- THE
COLLECTION METHOD NEXT RETURNS THE VALUE FROM THE NEXT HIGHER INDEX
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
DBMS_OUTPUT.PUT_LINE('THE INDEX
BEFORE 3RD INDEX IS '||VAR_NT.PRIOR(3));
DBMS_OUTPUT.PUT_LINE('THE VALUE
BEFORE 3RD INDEX IS '||VAR_NT(VAR_NT.PRIOR(3)));
END;
/
SQL> SET SERVEROUTPUT ON;
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
DBMS_OUTPUT.PUT_LINE('THE INDEX
BEFORE 3RD INDEX IS '||VAR_NT.NEXT(3));
DBMS_OUTPUT.PUT_LINE('THE VALUE
BEFORE 3RD INDEX IS '||VAR_NT(VAR_NT.NEXT(3)));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
DBMS_OUTPUT.PUT_LINE('VALUE AT
INDEX[5] BEFORE DELETE IS '||VAR_NT(5));
VAR_NT.DELETE(5);
DBMS_OUTPUT.PUT_LINE('VALUE AT
INDEX[5] AFRER DELETE IS '||VAR_NT(5));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
DBMS_OUTPUT.PUT_LINE('VALUE AT
INDEX[5] BEFORE DELETE IS '||VAR_NT(5));
VAR_NT.DELETE(5);
IF VAR_NT.EXISTS(5) THEN
DBMS_OUTPUT.PUT_LINE
('VALUE AT INDEX[5] AFTER DELETE IS '||VAR_NT(5));
ELSE
DBMS_OUTPUT.PUT_LINE('DATA
NOT FOUND');
END IF;
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
VAR_NT.DELETE(2, 6);
FOR I IN 1..VAR_NT.LAST
LOOP
IF VAR_NT.EXISTS(I) THEN
DBMS_OUTPUT.PUT_LINE('VALUE
AT INDEX ['||I||'] IS '||VAR_NT(I));
END IF;
END LOOP;
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
NT_OBJ MY_NEST_TABLE :=
MY_NEST_TABLE();
BEGIN
NT_OBJ(1) := 10;
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 1 IS '||NT_OBJ(1));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
NT_OBJ MY_NEST_TABLE :=
MY_NEST_TABLE();
BEGIN
NT_OBJ.EXTEND;
NT_OBJ(1) := 10;
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 1 IS '||NT_OBJ(1));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
NT_OBJ MY_NEST_TABLE :=
MY_NEST_TABLE();
BEGIN
NT_OBJ.EXTEND(3);
NT_OBJ(1) := 10;
NT_OBJ(2) := 20;
NT_OBJ(3) := 30;
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 1 IS '||NT_OBJ(1));
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 1 IS '||NT_OBJ(2));
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 1 IS '||NT_OBJ(3));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
NT_OBJ MY_NEST_TABLE :=
MY_NEST_TABLE();
BEGIN
NT_OBJ.EXTEND;
NT_OBJ(1) := 10;
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 1 IS '||NT_OBJ(1));
NT_OBJ.EXTEND(5, 1);
DBMS_OUTPUT.PUT_LINE('DATA AT
INDEX 4 IS '||NT_OBJ(1));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
NT_OBJ MY_NEST_TABLE :=
MY_NEST_TABLE(1, 2, 3, 4, 5);
BEGIN
NT_OBJ.TRIM;
DBMS_OUTPUT.PUT_LINE(NT_OBJ(I));
END LOOP;
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
NT_OBJ MY_NEST_TABLE :=
MY_NEST_TABLE(1, 2, 3, 4, 5);
BEGIN
NT_OBJ.TRIM(2);
DBMS_OUTPUT.PUT_LINE('AFTER TRIM
PROCEDURE CALL');
FOR I IN 1..NT_OBJ.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE(NT_OBJ(I));
END LOOP;
END;
/
SYNTAX: DECLARE
TYPE REF_CURSOR_NAME IS REF
CURSOR
RETURN(RETURN TYPE);
--- RETURN TYPE MUST ALWAYS
ONLY RECORD TYPE
SYNTAX: DECLARE
TYPE REF_CURSOR_NAME IS REF
CURSOR;
SQL> DECLARE
TYPE MY_REFCUR IS REF CURSOR
RETURN EMPLOYEES%ROWTYPE;
CUR_VAR MY_REFCUR;
REC_VAR EMPLOYEES%ROWTYPE;
BEGIN
OPEN CUR_VAR FOR SELECT * FROM
EMPLOYEES WHERE EMPLOYEE_ID = 100;
FETCH CUR_VAR INTO REC_VAR;
CLOSE CUR_VAR;
DBMS_OUTPUT.PUT_LINE('EMPLOYEE
'||REC_VAR.FIRST_NAME||' HAS SALARY '||REC_VAR.SALARY);
END;
/
SQL> DECLARE
TYPE MY_REC IS RECORD
(
EMP_SAL EMPLOYEES.SALARY%TYPE
);
TYPE REFCUR IS REF CURSOR
RETURN MY_REC;
CUR_VAR REFCUR;
AT_VAR EMPLOYEES.SALARY%TYPE;
BEGIN
OPEN CUR_VAR FOR SELECT SALARY
FROM EMPLOYEES WHERE EMPLOYEE_ID = 100;
FETCH CUR_VAR INTO AT_VAR;
CLOSE CUR_VAR;
DBMS_OUTPUT.PUT_LINE('SALARY
OF THE EMPLOYEE IS '||AT_VAR);
END;
/
SQL> DECLARE
TYPE WK_REFCUR IS REF CURSOR;
CUR_VAR WK_REFCUR;
F_NAME EMPLOYEES.FIRST_NAME
%TYPE;
EMP_SAL EMPLOYEES.SALARY%TYPE;
BEGIN
OPEN CUR_VAR FOR SELECT
FIRST_NAME, SALARY FROM EMPLOYEES WHERE EMPLOYEE_ID = 100;
FETCH CUR_VAR INTO F_NAME,
EMP_SAL;
CLOSE CUR_VAR;
DBMS_OUTPUT.PUT_LINE(F_NAME||'
'||EMP_SAL);
END;
/
SQL> DECLARE
CUR_VAR SYS_REFCURSOR;
F_NAME EMPLOYEES.FIRST_NAME
%TYPE;
EMP_SAL EMPLOYEES.SALARY%TYPE;
BEGIN
OPEN CUR_VAR FOR SELECT
FIRST_NAME, SALARY FROM EMPLOYEES WHERE EMPLOYEE_ID = 100;
FETCH CUR_VAR INTO F_NAME,
EMP_SAL;
CLOSE CUR_VAR;
DBMS_OUTPUT.PUT_LINE(F_NAME||'
'||EMP_SAL);
END;
/
1. SELECT-INTO
2. FETCH-INTO
3. RETURNING-
INTO
SQL> DECLARE
TYPE NT_FNAME IS TABLE OF
VARCHAR2(20); ---PLS-00642: local collection types not allowed in SQL statements
FNAME NT_FNAME;
BEGIN
SELECT FIRST_NAME INTO FNAME FROM
EMPLOYEES;
END;
/
SQL> DECLARE
TYPE NT_FNAME IS TABLE OF
VARCHAR2(20);
FNAME NT_FNAME;
BEGIN
SELECT FIRST_NAME BULK COLLECT
INTO FNAME FROM EMPLOYEES;
FOR I IN 1..FNAME.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE(I||' - '||
FNAME(I));
END LOOP;
END;
/
SQL> DECLARE
CURSOR EXP_CUR IS
SELECT FIRST_NAME FROM
EMPLOYEES;
SQL> DECLARE
CURSOR EXP_CUR IS
SELECT FIRST_NAME FROM
EMPLOYEES;
SQL> DECLARE
TYPE MY_ARRAY IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
COL_VAR MY_ARRAY;
TOT_REC NUMBER;
BEGIN
--POPULATE THE COLLECTION
FOR I IN 1..10 LOOP
COL_VAR(I):=9*I;
END LOOP;
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
VAR_NT.DELETE(3, 6);
FOR I IN 1..VAR_NT.LAST
LOOP
IF VAR_NT.EXISTS(I) THEN
DBMS_OUTPUT.PUT_LINE(VAR_NT(I));
ELSE
DBMS_OUTPUT.PUT_LINE('NO
DATA AT INDEX NUMBER '||I);
END IF;
END LOOP;
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
BEGIN
VAR_NT.DELETE(3, 6);
FORALL IDX IN 1..10
INSERT INTO TUT_78
VALUES(VAR_NT(IDX));
END;
/
SQL> DECLARE
TYPE MY_NEST_TABLE IS TABLE OF
NUMBER;
VAR_NT MY_NEST_TABLE :=
MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81, 90);
TOT_REC NUMBER;
BEGIN
VAR_NT.DELETE(3, 6);
FORALL IDX IN INDICES OF VAR_NT
INSERT INTO TUT_78
(MUL_TAB) VALUES(VAR_NT (IDX));
3. VALUES OF CLAUSE:
SQL> DECLARE
TYPE
MY_NEST_TABLE ISS TABLE OF NUMBER;
SOURCE_COL MY_NEST_TABLE := MY_NEST_TABLE(9, 18, 27, 36, 45, 54, 63, 72, 81,
90);
TYPE
MY_ARRAY IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER
INDEX_COL MY_ARRAY;
BEGIN
INDEX_COL(1) := 3
INDEX_COL(5) := 7
INDEX_COL(12):= 8
INDEX_COL(28):=10
FORALL IDX IN VALUES OF INDEX_COL
SQL> DECLARE
SQL_QRY VARCHAR2(150);
EMP_TOT NUMBER(3);
BEGIN
SQL_QRY := 'SELECT COUNT(*) FROM
EMPLOYEES';
EXECUTE IMMEDIATE SQL_QRY INTO
EMP_TOT;
DBMS_OUTPUT.PUT_LINE('TOTAL
EMPLOYEES ARE '||EMP_TOT);
END;
/
SQL> BEGIN
CREATE TABLE TUT_81
(
TUT_NUM NUMBER(3),
--PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
TUT_NAME VARCHAR2(50)
);
END;
/
SQL> DECLARE
DDL_QRY VARCHAR2(150);
BEGIN
DDL_QRY := 'CREATE TABLE TUT_82
(
TUT_NUM NUMBER(3),
TUT_NAME VARCHAR2(50)
)';
EXECUTE IMMEDIATE DDL_QRY;
END;
/
SQL> DECLARE
DDL_QRY VARCHAR2(150);
BEGIN
DDL_QRY := 'CREATE TABLE
TUT_83'||
'('||
'TUT_NUM
NUMBER(5),'||
'TUT_NAME
VARCHAR2(50),'||
'CONSTRAINT TUT_PK
PRIMARY KEY(TUT_NUM)'||
')';
EXECUTE IMMEDIATE DDL_QRY;
END;
/
SQL> DECLARE
DDL_QRY VARCHAR2(50);
BEGIN
DDL_QRY := 'ALTER TABLE TUT_83
ADD TUT_DATE DATE';
EXECUTE IMMEDIATE DDL_QRY;
END;
/
SQL> DECLARE
SQL_SMT VARCHAR2(150);
BEGIN
SQL_SMT := 'UPDATE STU_INFO SET
STUDENT_NAME = :NEW_NAME
WHERE STUDENT_NAME
= :OLD_NAME';
EXECUTE IMMEDIATE SQL_SMT USING
'SURESH', 'LEO';
END;
/
SQL> DECLARE
SQL_SMT VARCHAR2(150);
BEGIN
SQL_SMT := 'UPDATE STU_INFO SET
STUDENT_NAME = :NEW_NAME
WHERE STUDENT_NAME
= :OLD_NAME';
EXECUTE IMMEDIATE SQL_SMT USING
'SURESH'; --ORA-01008: not all variables bound
END;
/
SQL> SET SERVEROUTPUT
ON;
SQL> DECLARE
SQL_SMT VARCHAR2(150);
BEGIN
SQL_SMT := 'UPDATE :TABLE_NAME
SET STUDENT_NAME = :NEW_NAME
WHERE STUDENT_NAME
= :OLD_NAME';
EXECUTE IMMEDIATE SQL_SMT USING
'STU_INFO','SUDHAKAR', 'SURESH'; ---ORA-00903: invalid table name
END;
/
SQL> DECLARE
TYPE NT_FNAME IS TABLE OF
VARCHAR2(60);
FNAME NT_FNAME;
SQL_QRY VARCHAR2(150);
BEGIN
SQL_QRY := 'SELECT FIRST_NAME
BULK COLLECT INTO FNAME FROM EMPLOYEES'; --ORA-03001: unimplemented feature
EXECUTE IMMEDIATE SQL_QRY;
END;
/
SQL> DECLARE
TYPE NT_FNAME IS TABLE OF
VARCHAR2(60);
FNAME NT_FNAME;
SQL_QRY VARCHAR2(150);
SQL> BEGIN
SQL_QRY := 'SELECT FIRST_NAME
FROM EMPLOYEES';
EXECUTE IMMEDIATE SQL_QRY BULK
COLLECT INTO FNAME;
FOR I IN 1..FNAME.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(I||' - '||
FNAME(I));
END LOOP;
END;
/
SQL> DECLARE
PL_BLK VARCHAR2(250);
BEGIN
PL_BLK := 'DECLARE
VAR_USER
VARCHAR2(10);
BEGIN
SELECT USER INTO
VAR_USER FROM DUAL;