PL SQL Quick Reference
PL SQL Quick Reference
ORACLE:
PL/SQL
QUICK
REFERENCE
By:
Gajendra Reddy Atla
CONTENTS
1. INTRODUCTION TO PL/SQL 4
• About PL/SQL
• Advantages of PL/SQL
• PL/SQL Execution Environment
• PL/SQL block structure
• PL/SQL Block types
• Parameters
2. VARIABLES 9
3. CONTROL STRUCTURES 12
• Conditional Control
• Iterative Control
• Sequential Control
4. CURSORS 17
• Types of Cursors
• Difference B/W Normal Cursor & Ref Cursor
• Cursor For Loop
• Cursor with Return statement
• Cursor attributes
5. PACKAGES 22
• Introduction
• Advantages
• Package Components
• Types of Packages
• Creating New Package
• Referencing Package Components
• Using Oracle Supplied Packages
6. TRIGGERS 26
• Introduction
• Parts of a Trigger
• Types of Triggers
• Order of Trigger Firing
• Dropping, Disabling and Enabling
• Examples
7. EXCEPTION HANDLING 32
• Introduction
• Predefined Exception
PL/SQL Quick Reference By A.G.Reddy
3
• User-defined Exception
• RAISE_APPLICATION_ERROR
• WHEN OTHERS Clause
• SQLCODE and SQLERRM
• Raising Exceptions
8. COLLECTIONS 35
• Introduction
• Nested Table
• Varray
• Index-By Table
• Collection Methods
• Bulk Collect
9. OVERLOADING 40
1. INTRODUCTION TO PL/SQL
PL/SQL Quick Reference By A.G.Reddy
4
About PL/SQL:
• PL/SQL stands for Procedural Language/SQL.
• Pl/SQL is the procedural extension to SQL with design features of programming languages.
• Data manipulation and query statements of SQL are included with in procedural units of code.
• The basic unit in PL/SQL is a block.
• All PL/SQL programs are made up of blocks, which can be nested within each other.
• Typically, each block performs a logical action in the program.
Advantages of PL/SQL:
PL/SQL is a completely portable, high-performance transaction processing language that offers the
following advantages:
1) Support for SQL.
2) Higher productivity.
3) Better performance.
4) Portability.
5) Integration with Oracle.
6) Modularize program development.
a) We can Group logically related statements with in blocks.
b) We can place reusable PL/SQL code for future use in libraries.
7) Programming with control structures. (Like for, while loops).
Higher Productivity:
PL/SQL adds functionality to non-procedural tools such as Oracle Forms and Oracle Reports. With PL/SQL in
these tools, you can use familiar procedural constructs to build applications. For example, you can use an entire
PL/SQL block in an Oracle Forms trigger. You need not use multiple trigger steps, macros, or user exits.
Thus, PL/SQL increases productivity by putting better tools in your hands. Moreover, PL/SQL is the same
in all environments. As soon as you master PL/SQL with one Oracle tool, you can transfer your
knowledge to other tools, and so multiply the productivity gains. For example, scripts written with one
tool can be used by other tools.
Better Performance
Without PL/SQL, Oracle must process SQL statements one at a time. Each SQL statement results in
another call to Oracle and higher performance overhead. In a networked environment, the overhead can
become significant. Every time a SQL statement is issued, it must be sent over the network, creating more
traffic. However, with PL/SQL, an entire block of statements can be sent to Oracle at one time. This can
drastically reduce communication between your application and Oracle.
Portability:
The call to the oracle engine needs to be made only once to execute any number of SQL statements, if
these SQL statements are bundled inside a PL/SQL block.
1. PROCEDURE:
• PL/SQL procedures behave very much like procedures in other programming language.
• Procedures are traditionally the workhorse of the coding world.
Simple Procedure
/* Finds the given number is odd or even */
create or replace procedure prc_even_odd(i_number in number,
o_result out varchar2)
is
begin
if (mod(i_number,2) = 0) then
o_result := 'EVEN';
else
o_result := 'ODD';
end prc_even;
2. FUNCTION:
• Functions are traditionally the smaller, more specific pieces of code.
• Functions must return a value.
• Generally used for calculations.
Simple Function
5 Functions used for calculation purpose Used for data processing purpose
To overcome all these The PL/SQL has one more block called “Anonymous Block”.
3 ANONYMOUS BLOCK:
Anonymous blocks are unnamed PL/SQL blocks. The anonymous block is missing the header section
altogether. Instead it simply uses the DECLARE reserved word to mark the beginning of its optional
declaration section. Anonymous blocks can also serve as nested blocks inside procedures, functions, and
other anonymous blocks.
The Below function objective is to select salary of a particular employee and ‘y’ if data exists. But
the function is able to return one value. To overcome this we have declared one out parameter & one
return statement.
Anonymous Block
declare
a number;
b varchar2(10);
begin
b := fn_test(101,a);
dbms_output.put_line(b);
dbms_output.put_line(a);
end;
Parameters:
• Named PL/SQL programs (procedures and functions) can take parameters.
• Parameters are named variables that are available to a program and that modify program
behavior and/or data.
• Parameters are optional on both procedures and functions.
• Parameters are declared when a procedure or function are declared and are declared
between an open and a close parenthesis (()).
• There are three types of parameter:
1. IN
2. OUT and
3. IN OUT
1) An IN parameter is used an input only. An IN parameter cannot be changed
by the called program.
2) An OUT parameter is initially NULL. The program assigns the parameter a
value and that value is returned to the calling program.
3) An IN OUT parameter may or may not have an initial value. That initial
value may or may not be modified by the called program. Any changes made to the parameter
are returned to the calling program.
Parameters are declared with data types but without data type length or precision. That means that
a parameter may be declared as VARCHAR2 but it will not be declared with a length component
(VARCHAR2 (30) would not be valid). Parameters may also be assigned a default value. You can either
use the assignment operator (:=) or use the DEFAULT keyword. When a parameter has a default value,
you do not need to include that parameter in the call. You MUST always include IN OUT and OUT
parameters.
2. VARIABLES
Information is transmitted between a PL/SQL program and the database through variables. Every
variable has a specific type associated with it.
Types of variables:
S.No Type Sub Type
Scalar
Composite
3 Declaring a variable with an initial value (not a Message varchar2 (10):= 'Example';
constant):
DBMS_OUTPUT.PUT_LINE:
• An Oracle-supplied packaged procedure
• An alternative for displaying data from a PL/SQL block
• Must be enabled in SQL*Plus with
SET SERVEROUTPUT ON
According to the structure theorem, any computer program can be written using the basic control
structures shown in Figure. They can be combined in any way necessary to deal with a given problem.
Control Structures:
CONDITIONAL CONTROL:
Often, it is necessary to take alternative actions depending on circumstances. The IF statement lets
you execute a sequence of statements conditionally. That is, whether the sequence is executed or not
depends on the value of a condition. There are three forms of IF statements: IF-THEN, IF-THEN-ELSE,
and IF-THEN-ELSIF.
IF-THEN-ELSE-END IF
create or replace procedure prc_cs
is
n number;
begin
dbms_output.put_line('Enter any number');
n:=&number;
if n>5 then
dbms_output.put_line('Entered number greater than 5');
else
dbms_output.put_line('Entered number less than 5');
end if;
end;
IF-THEN-ELSEIF-ELSE-END IF
create or replace procedure prc_test
is
day varchar2(3):=to_char(sysdate,'dy');
begin
if day='sat' then
dbms_output.put_line('enjoy weekend');
elsif day='sun' then
dbms_output.put_line('enjoy weekend');
else
dbms_output.put_line('have a nice day');
end if;
end;
ITERATIVE CONTROL:
LOOP statement executes the body statements multiple times. The statements are placed between
LOOP – END LOOP keywords. EXIT statement is used inside LOOP to terminate it.
BASIC LOOP
create or replace procedure prc_num
is
n number:=0;
begin
loop
dbms_output.put_line(n);
n:=n+1;
exit when n>10;
end loop;
end;
FOR LOOP
create or replace procedure prc_num1
is
n number:=0;
begin
for i in 1..100 loop
dbms_output.put_line(n);
n:=n+1;
end loop;
end;
SEQUENTIAL CONTROL:
Unlike the IF and LOOP statements, the GOTO and NULL statements are not crucial to PL/SQL
programming. The GOTO statement is seldom needed. Occasionally, it can simplify logic enough to
warrant its use. The NULL statement can improve readability by making the meaning and action of
conditional statements clear.
1). GOTO: The GOTO statement branches to a label unconditionally. The label must be unique within its
scope and must precede an executable statement or a PL/SQL block. When executed, the GOTO statement
transfers control to the labeled statement or block. The labeled statement or block can be down or up in
the sequence of statements.
GOTO Statement
create or replace procedure prc_goto is
n number;
begin
dbms_output.put_line('Enter any Number');
n:=&number;
if n>10 then
goto print;
end if;
dbms_output.put_line('less than 10');
<<print>>
dbms_output.put_line('Greater than 10');
end;
Types of Cursors:
S.No TYPES OF CURSORS
1 Implicit Cursor -------
a). Simple cursor
2 Explicit Cursor b). Parameterized cursor
c). Ref Cursor
d). Cursor With Return
Statement
Declaring a cursor is possible through CURSOR statement. Opening a cursor is possible through
OPEN statement. Fetching rows from the cursor is possible through FETCH statement. Closing a cursor is
possible through CLOSE statement. So, it is very easy to remember all four operations with the
cursor. These four options are all automatically handled by Oracle in the case of IMPLICIT cursor (like
implicit FOR loop with SELECT).
Parameterized cursor
create or replace procedure prc_cur_details(i_location in dept.loc%type)
is
cursor c_loc is select deptno
from dept
where loc = i_location;
cursor c_emp(l_deptno dept.deptno%type) is select *
from emp
where deptno = l_deptno;
begin
for rec_loc in c_loc loop
for rec_emp in c_emp(rec_loc.deptno) loop
dbms_output.put_line(rec_emp.deptno ||' '||rec_emp.empno||' '||rec_emp.ename);
end loop;
end loop;
end;
Ref Cursor
1 create or replace procedure prc_ref(i_deptno in dept.deptno%type
2 ,o_result out sys_refcursor)
3 is
4 begin
5 open o_result for select empno
6 ,ename
7 ,sal
8 ,job
9 ,hiredate
10 from emp
11 where deptno = i_deptno;
12 end;
1 Doesn't have return type. Have a return type. Basically a data type
2 Normal cursors are static cursors. Ref cursors are Dynamic cursors.
3 We can't able to pass like parameter. Ref cursor used for passing cursor parameter.
4 The SQL query has to be defined at The cursor declaration is not associated with any
the time of declaring the cursor itself. SQL query; it is associated with a query at a
later stage this brings in a lot of flexibility as
different SQL queries can be associated with the
cursor.
5 Explicit cursors are generally used to Ref cursor is a cursor variable that point to any
work with more than one row cursor, mainly used for returning the cursor
output.
Cursor For Loop:
A cursor FOR loop is a loop that is associated with (actually defined by) an explicit cursor or a
SELECT statement incorporated directly within the loop boundary. Use the cursor FOR loop whenever
(and only if) you need to fetch and process each and every record from a cursor. The CURSOR FOR Loop
will terminate when all of the records in the cursor have been fetched.
The beauty of using a PL/SQL cursor FOR LOOP is that Oracle automatically Opens the cursor,
the results are automatically Fetched and when all rows have been returned, Oracle automatically Closes
the cursor for you.
In the previous section we have learned that a sequence of steps is followed to define and use a
cursor as follows.
Since these steps are almost always followed, Oracle provides a way to let PL/SQL perform most
of the steps. This is called the CURSOR FOR loop. As in the name, it uses a FOR loop to process the
cursor.
Cursor attributes:
Cursor attributes are variables that take some value about the status of the cursor. These values are
automatically set by Oracle and the programmer can read them not write values for them. There are four
cursor attributes. They are
1. %FOUND
2. %ISOPEN
3. %NOTFOUND
4. %ROWCOUNT
1. %FOUND:
After a cursor is opened before the first fetch, the value of this variable is null. After the first fetch,
if the query returns one or more rows as result set, this variable is set to TRUE. When a fetch is made after
the last row of the result set is reached, this variable is set to FALSE.
This variable is extensively used to in stored procedures to handle exceptions when a query returns
no data set. If this variable is referenced before the cursor is opened, an exception INVALID_CURSOR is
raised.
2. %ISOPEN
This variable is set to TRUE if a cursor is opened and false when the cursor is closed.
3. %NOTFOUND
This variable is a logical opposite of %FOUND. This variable is set to TRUE if the last fetch
returns no rows an FALSE when the last fetch returns a row. This can also be used in exception handing
when a query returns no rows.
4. %ROWCOUNT
This variable acts like a counter. It is set to zero when a cursor is opened. Thereafter, with each
fetch, the value of this variable is incremented by 1 if the fetch returns a row. This variable is handy when
processing needs to be done for only a few rows of the result set.
5. PACKAGES
Introduction:
A package is a collection of PL/SQL elements that are "packaged" or grouped together within a
special BEGIN-END syntax, a kind of "meta-block." Here is a partial list of the kinds of elements you can
place in a package:
1. Cursors
2. Variables (scalars, records, tables, etc.) and constants
3. Exception names and pragmas for associating an error number with an exception
4. PL/SQL table and record TYPE statements
5. Procedures and functions
Packages are among the least understood and most underutilized features of PL/SQL. That's a
shame because the package structure is also one of the most useful constructs for building well-designed
PL/SQL-based applications. Packages provide a structure to organize your modules and other PL/SQL
elements. They encourage proper structured programming techniques in an environment that often
befuddles the implementation of structured programming. When you place a program unit into a package
you automatically create a "context" for that program. By collecting related PL/SQL elements in a
package, you express that relationship in the very structure of the code itself. Packages are often called
"the poor man's objects" because they support some, but not all, object-oriented rules.
Advantages:
Packages have many advantages over standalone procedures and functions. For example, they:
• Let you organize your application development more efficiently.
• Let you grant privileges more efficiently.
• Let you modify package objects without recompiling dependent schema objects.
• Enable Oracle to read multiple package objects into memory at once.
• Let you overload procedures or functions. Overloading means creating multiple procedures
with the same name in the same package, each taking arguments of different number or data type.
• Can contain global variables and cursors that are available to all procedures and functions
in the package.
Package Components:
PL/SQL packages have two parts:
1. The specification and
2. The body
The specification is the interface to your application; it declares the types, variables, constants,
exceptions, cursors, and subprograms available for use. The specification holds public declarations that
are visible to your application.
The body fully defines cursors and subprograms, and so implements the specification. The body holds
implementation details and private declarations that are hidden from your application.
Types of Package:
Although any PL/SQL package must have the same structure and follow the same rules, there are
different types of packages that will play different roles in your application.
1). Create the package specification with the CREATE PACKAGE statement:
You can declare program objects in the package specification. Such objects are called public
objects. Public objects can be referenced outside the package, as well as by other objects in the package.
2). Create the package body with the CREATE PACKAGE BODY statement.
You can declare and define program objects in the package body.
Example1:
The following example shows a package specification for a package named pck_const.
Package Specification
create or replace package pck_const is
end pck_const;
The body for this package defines the prc_test procedure as follows:
Package Body
create or replace package body pck_const is
Example2:
The following example shows a package specification for a package named Employee_Management. The
package contains one stored function and two stored procedures.
Package Specification
The body for this package defines the function and the procedures:
Package Body
/*The function accepts all arguments for the fields in the employee table except for the
employee number. A value for this field is supplied by a sequence. The function returns the
sequence number generated by the call to this function.*/
new_empno NUMBER(10);
BEGIN
SELECT emp_sequence.NEXTVAL INTO new_empno FROM dual;
/*The procedure deletes the employee with an employee number that corresponds
to the argument emp_id. If no employee is found, then an exception is
raised.*/
BEGIN
DELETE FROM emp WHERE empno = emp_id;
IF SQL%NOTFOUND THEN
raise_application_error(-20011, 'Invalid Employee
Number: ' || TO_CHAR(emp_id));
END IF;
END fire_emp;
BEGIN
-- If employee exists, then update salary with increase.
UPDATE emp
SET sal = sal + sal_incr
WHERE empno = emp_id;
IF SQL%NOTFOUND THEN
raise_application_error(-20011, 'Invalid Employee
Number: ' || TO_CHAR(emp_id));
END IF;
END sal_raise;
END employee_management;
Certain packages are not installed automatically. For these packages Special installation instructions
are needed.
To call a PL/SQL function from SQL, you must either own the function or have EXECUTE privileges
on the function. To select from a view defined with a PL/SQL function, you must have SELECT
privileges on the view. No separate EXECUTE privileges are needed to select from the view.
6. TRIGGERS
Introduction:
Triggers are a special PL/SQL construct similar to procedures. However, a procedure is executed
explicitly from another block via a procedure call, while a trigger is executed implicitly whenever the
triggering event happens. The triggering event is either a INSERT, DELETE, or UPDATE command. The
timing can be either BEFORE or AFTER. The trigger can be either row-level or statement-level, where
the former fires once for each row affected by the triggering statement and the latter fires once for the
whole statement.
Below figure shows a database application with some SQL statements that implicitly fire several
triggers stored in the database. Notice that the database stores triggers separately from their associated
tables.
PARTS OF A TRIGGER:
A trigger has three basic parts:
1. A triggering event or statement
2. A trigger restriction
3. A trigger action
An INSERT, UPDATE, or DELETE statement on a specific table (or view, in some cases)
A CREATE, ALTER, or DROP statement on any schema object
A database startup or instance shutdown
A specific error message or any error message
A user logon or logoff
If the triggers are row triggers, the statements in a trigger action have access to column values of the
row being processed by the trigger. Correlation names provide access to the old and new values for each
column.
TYPES OF TRIGGERS:
This section describes the different types of triggers:
1. Row Triggers and Statement Triggers
2. BEFORE and AFTER Triggers
3. INSTEAD OF Triggers
4. Triggers on System Events and User Events
1). Row Triggers and Statement Triggers
When you define a trigger, you can specify the number of times the trigger action is to be run:
• Once for every row affected by the triggering statement, such as a trigger fired by an UPDATE
statement that updates many rows
• Once for the triggering statement, no matter how many rows it affects
Row Triggers:
A row trigger is fired each time the table is affected by the triggering statement. For example, if an
UPDATE statement updates multiple rows of a table, a row trigger is fired once for each row affected by
the UPDATE statement. If a triggering statement affects no rows, a row trigger is not run.
Row triggers are useful if the code in the trigger action depends on data provided by the triggering
statement or rows that are affected. For example, Figure 17-3 illustrates a row trigger that uses the values
of each row affected by the triggering statement.
Statement Triggers:
A statement trigger is fired once on behalf of the triggering statement, regardless of the number of
rows in the table that the triggering statement affects, even if no rows are affected. For example, if a
DELETE statement deletes several rows from a table, a statement-level DELETE trigger is fired only
once.
Statement triggers are useful if the code in the trigger action does not depend on the data provided by
the triggering statement or the rows affected. For example, use a statement trigger to:
• Make a complex security check on the current time or user
• Generate a single audit record
BEFORE and AFTER triggers fired by DML statements can be defined only on tables, not on views.
However, triggers on the base tables of a view are fired if an INSERT, UPDATE, or DELETE statement is
issued against the view. BEFORE and AFTER triggers fired by DDL statements can be defined only on
the database or a schema, not on particular tables.
BEFORE Triggers:
BEFORE triggers run the trigger action before the triggering statement is run. This type of trigger is
commonly used in the following situations:
• When the trigger action determines whether the triggering statement should be allowed to
complete. Using a BEFORE trigger for this purpose, you can eliminate unnecessary processing
of the triggering statement and its eventual rollback in cases where an exception is raised in the
trigger action.
• To derive specific column values before completing a triggering INSERT or UPDATE
statement.
AFTER Triggers:
AFTER triggers run the trigger action after the triggering statement is run.
BEFORE statement trigger: Before executing the triggering statement, the trigger action is
run.
BEFORE row trigger: Before modifying each row affected by the triggering statement and
before checking appropriate integrity constraints, the trigger action is run, if the trigger
restriction was not violated.
AFTER row trigger: After modifying each row affected by the triggering statement and
possibly applying appropriate integrity constraints, the trigger action is run for the current row
provided the trigger restriction was not violated. Unlike BEFORE row triggers, AFTER row
triggers lock rows.
AFTER statement trigger: After executing the triggering statement and applying any
deferred integrity constraints, the trigger action is run.
You can write normal INSERT, UPDATE, and DELETE statements against the view and the
INSTEAD OF trigger is fired to update the underlying tables appropriately. INSTEAD OF triggers are
activated for each row of the view that gets modified.
4). Triggers on System Events and User Events
You can use triggers to publish information about database events to subscribers. Applications can
subscribe to database events just as they subscribe to messages from other applications. These database
events can include:
System events
• Database startup and shutdown
• Server error message events
User events
• User logon and logoff
• DDL statements (CREATE, ALTER, and DROP)
• DML statements (INSERT, DELETE, and UPDATE)
Triggers on system events can be defined at the database level or schema level. For example, a
database shutdown trigger is defined at the database level:
Dropping Triggers:
To drop a trigger:
• drop trigger <trigger_name>;
Disabling/Enabling Triggers:
To disable or enable a trigger:
• alter trigger <trigger_name> {disable|enable};
TRIGGER EXAMPLES:
TRIGGER EXAMPLE#1
TRIGGER EXAMPLE#2
TRIGGER EXAMPLE#3
begin
if inserting then
insert into audit_log(user_name
,date1
,action)
values(USER
,sysdate
,'INSERT');
elsif updating then
insert into audit_log(user_name
,date1
,action)
values(USER
,sysdate
,'UPDATE');
elsif deleting then
insert into audit_log(user_name
,date1
,action)
values(user
,sysdate
,'DELETE');
end if;
commit;
end trg_student;
7. EXCEPTION HANDLING
INTRODUCTION:
An exception is an abnormal situation which becomes an obstacle in the normal flow of the
program. When you are writing a PL/SQL block which is a procedural extension of SQL, there comes the
following sequence of blocks:
1). Declare. 2) Begin.3). Exception, 4). End
In the exception block we have to define a user defined Exception handler or system defined
handler to track the error occurred line. This is called Exception handling in Oracle which helps to handle
datatype discrepancies or Constraint type problems or any other kinds of abnormal situations.
When an exception occurs (is raised) in a PL/SQL block, its execution section immediately
terminates. Control is passed to the exception section.
PREDEFINED EXCEPTION:
Predefined exception is raised automatically whenever there is a violation of Oracle coding rules.
Predefined exceptions are those like ZERO_DIVIDE, which is raised automatically when we try to divide
a number by zero. Other built-in exceptions are given below. You can handle unexpected Oracle errors
using OTHERS handler. It can handle all raised exceptions that are not handled by any other handler. It
must always be written as the last handler in exception block.
Predefined exception handlers are declared globally in package STANDARD. Hence we need not
have to define them rather just use them. Every exception in PL/SQL has an error number and error
message; some exceptions also have names as below:
ZERO_DIVIDE Exception
create or replace procedure prc_zero
Is
N number;
Begin
N:=10/0;
Exception
When ZERO_DIVIDE then
dbms_output.put_line(‘Zero Devide Error’);
end;
NO_DATA_FOUND Exception
create or replace procedure prc_emp_details(i_eno in number,
Name out varchar2,
Salary out number,
Dept out number)
Is
Begin
Select ename, sal, deptno into name, salary, dept
From emp
Where empno=i_eno;
Exception
When NO_DATA_FOUND then
dbms_output.put_line(‘Employee number does not exists’);
USER-DEFINED EXCEPTION:
A User-defined exception has to be defined by the programmer. User-defined exceptions are
declared in the declaration section with their type as exception. They must be raised explicitly using
RAISE statement, unlike pre-defined exceptions that are raised implicitly. RAISE statement can also be
used to raise internal exceptions.
User-defined exception:
RAISE_APPLICATION_ERROR:
To display your own error messages one can use the built-in RAISE_APPLICATION_ERROR.
They display the error message in the same way as Oracle errors. You should use a negative number
between –20000 to –20999 for the error number and the error message should not exceed 512 characters.
RAISE_APPLICATION_ERROR:
RAISING EXCEPTIONS:
With the above explanation it is clear that an exception can be raised in three ways:
1. By the PL/SQL runtime engine
2. By an explicit RAISE statement in your code
3. By a call to the built-in function RAISE_APPLICATION_ERROR
8. COLLECTIONS
INTRODUCTION:
Just about all modern programming languages provide support for collections. A collection can be
loosely defined as a group of ordered elements, all of the same type, that allows programmatic access to
its elements through an index. Commonly used collection types used in the programming world include
arrays, maps, and lists.
Probably the biggest advantage a collection can provide is improved application performance.
Developers utilize collections to 'cache' static data that needs to be regularly accessed. This results in
reduced calls to a database. As I stated earlier, PL/SQL programs are a good place to make expensive SQL
calls but that doesn't mean that we shouldn't try to keep those calls to a minimum.
Oracle uses collections in PL/SQL the same way other languages use arrays. Oracle provides three
basic collections, each with an assortment of methods.
The number 1
The number 2
The number 4
The number 5
VARRAY COLLECTIONS:
A VARRAY is similar to a nested table except you must specify an upper bound in the declaration.
Like nested tables they can be stored in the database, but unlike nested tables individual elements cannot
be deleted so they remain dense:
Varray Collections
SET SERVEROUTPUT ON SIZE 1000000
DECLARE
TYPE table_type IS VARRAY(5) OF NUMBER(10);
v_tab table_type;
v_idx NUMBER;
BEGIN
-- Initialise the collection with two values.
v_tab := table_type(1, 2);
-- Traverse collection
v_idx := v_tab.FIRST;
<< display_loop >>
WHILE v_idx IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE('The number ' || v_tab(v_idx));
v_idx := v_tab.NEXT(v_idx);
END LOOP display_loop;
END;
/
The number 1
The number 2
The number 3
The number 4
The number 5
INDEX-BY TABLES:
The first type of collection is known as index-by tables. These behave in the same way as arrays
except that have no upper bounds, allowing them to constantly extend. As the name implies, the collection
is indexed using BINARY_INTEGER values, which do not need to be consecutive. The collection is
extended by assigning values to an element using an index value that does not currently exist.
Index-By Table
SET SERVEROUTPUT ON SIZE 1000000
DECLARE
TYPE table_type IS TABLE OF NUMBER(10)
INDEX BY BINARY_INTEGER;
v_tab table_type;
v_idx NUMBER;
BEGIN
-- Initialise the collection.
<< load_loop >>
FOR i IN 1 .. 5 LOOP
v_tab(i) := i;
END LOOP load_loop;
The number 1
The number 2
The number 4
The number 5
COLLECTION METHODS:
A variety of methods exist for collections, but not all are relevant for every collection type:
Examlple#1:
In the below example t_varchar is declared in a package
Nested table
BULKCOLLECT:
Executing SQL statements in PLSQL programs causes a context switch between the PLSQL
engine and the SQL engine. Too many context switches may degrade performance dramatically. In order
to reduce the number of these context switches we can use a feature named bulk binding. Bulk binding lets
us to transfer rows between the SQL engine and the PLSQL engine as collections. Bulk binding is
available for select, insert, delete and update statements.
BULKCOLLECT#1
BULKCOLLECT#2
You can declare local or packaged stored procedures with exactly the same name, as long as their
parameters are different by at least one of these factors:
1. The Number Of Parameters,
2. Names Of Parameters,
3. Order Of Parameters, Or
4. The Datatype Family Of The Parameters.
Names Of Parameters
SQL> declare
2 function getArea(i_rad NUMBER, i_prec NUMBER)
3 return NUMBER
4 is
5 v_pi NUMBER:=3.14;
6 begin
7 return trunc(v_pi * (i_rad ** 2),i_prec);
8 end;
9 function getArea(i_length NUMBER, i_width NUMBER)
10 return NUMBER
11 is
12 begin
13 return i_length * i_width;
14 end;
15 begin
16 DBMS_OUTPUT.put_line('Area (R=3): '||getArea(i_rad=>3,i_prec=>1));
17 DBMS_OUTPUT.put_line('Area (2x3): '||getArea(i_length=>2,i_width=>3));
18 end;
19 /
Area (R=3): 28.2
Area (2x3): 6
Restrictions on overloading:
1. You can't overload standalone procedures or functions.
2. The second definition simply overwrites the first one.
3. You can't overload functions that differ only by the datatype of the return value.
4. If you need to implement this requirement, use overloaded procedures with OUT
parameters.
PL/SQL is Oracle's Procedural Language extension to SQL. PL/SQL's language syntax, structure and
data types. Some of the statements provided by PL/SQL:
set serveroutput on
begin
dbms_output.put_line('Look Ma, I can print from PL/SQL!!!');
end;
14. How does one get the value of a sequence into a PL/SQL variable?
As you might know, one cannot use sequences directly from PL/SQL. Oracle (for some silly reason)
prohibits this:
i := sq_sequence.NEXTVAL;
However, one can use embedded SQL statements to obtain sequence values:
DECLARE
CURSOR dept_cur IS
SELECT deptno
FROM dept
ORDER BY deptno;
END LOOP;
END;
17. How often should one COMMIT in a PL/SQL loop? / What is the best commit strategy?
Contrary to popular belief, one should COMMIT less frequently within a PL/SQL loop to prevent
ORA-1555 (Snapshot too old) errors. The higher the frequency of commit, the sooner the extents in the
undo/ rollback segments will be cleared for new transactions, causing ORA-1555 errors.
18. I can SELECT from SQL*Plus but not from PL/SQL. What is wrong?
PL/SQL respect object privileges given directly to the user, but does not observe privileges given
through roles. The consequence is that a SQL statement can work in SQL*Plus, but will give an error in
PL/SQL. Choose one of the following solutions:
Another way this error can occur is if the trigger has statements to change the primary, foreign or
unique key columns of the table off which it fires. If you must have triggers on tables that have referential
constraints, the workaround is to enforce the referential integrity through triggers as well.
• A row-level trigger cannot query or modify a mutating table. (Of course, NEW and OLD still
can be accessed by the trigger).
• A statement-level trigger cannot query or modify a mutating table if the trigger is fired as the
result of a CASCADE delete.
• Etc.
As workaround, one can use autonomous transactions. Autonomous transactions execute separate from
the current transaction. Unlike regular triggers, autonomous triggers can contain COMMIT and
ROLLBACK statements.
SET#2
1. What Is PL/SQL Language Case Sensitive?
PL/SQL language is not case sensitive: