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

Oracle PLSQL and SQL

This document discusses various PL/SQL features for working with data accessed via SQL, including cursors, collections like associative arrays and nested tables, and special data types like %TYPE and %ROWTYPE. It provides examples of using explicit and implicit cursors, cursor attributes, ref cursors, and the different types of collections - associative arrays, nested tables, and variable arrays.

Uploaded by

Venkatesan
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
119 views

Oracle PLSQL and SQL

This document discusses various PL/SQL features for working with data accessed via SQL, including cursors, collections like associative arrays and nested tables, and special data types like %TYPE and %ROWTYPE. It provides examples of using explicit and implicit cursors, cursor attributes, ref cursors, and the different types of collections - associative arrays, nested tables, and variable arrays.

Uploaded by

Venkatesan
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

PL/SQL and SQL -1-

Working with data that is accessed buy SQL can include the use of

• Cursors (Explicit, Implicit and Reference)


• Associative arrays
• Nested tables
• Variable arrays (Varrays)

Explicit Cursors

A cursor acts logically as a pointer to a result set, you can move the pointer through the result set processing
each row until the end. There are methods for the cursor

cursor <cursor_name> is <sql statement>;


Creating
cursor test_cursor is select name from employees
Opening open cursor [argument,argument];
Fetching data fetch cursor into variable1, variable2......;
Closing close cursor

Cursors have attributes that can be used and are obtained by using cursor.attribute_name

%ISOPEN contains true if the cursor is currently open false if not.


can contain serveral values

%FOUND NULL - before a fetch on the cursor


TRUE - if a row was fetched successfully
FALSE - if a row was fetched unsuccessfully
%NOTFOUND oppostite to %FOUND
%ROWCOUNT contains the number of rows fetched so far.

Now for an example

Cursor example create or replace procedure test_cursor_proc_1


IS
first_name varchar2(30);
last_name varchar2(30);

cursor test_cursor IS select fname, lname from employees;


BEGIN
open test_cursor;

loop
fetch test_cursor into first_name, last_name;
exit when test_cursor%NOTFOUND;
PL/SQL and SQL -2-

dbms_output.put_line( 'First Name: ' || first_name || 'Surname: ' || last_name);


end loop;
close test_cursor;
END;

Special Data Types

In the last example we had to specify the data types, Oracle can automatically match the data types for us and
there are two data types that allow us to do this %type and %rowtype.

is used to declare a field with the same type as that of a specified table column

DECLARE
empname emp.ename%TYPE
%TYPE
BEGIN
select ename into empname from emp where rownum = 1;
dbms_ouput.put_line( 'Name: ' || empname);
END;
is used to declare a record with the same types as found in the specified table, view or cursor

DECLARE
emp emp%ROWTYPE
%ROWTYPE
BEGIN
emp.empno := 10;
emp.ename := 'vallep';
END;

For Cursor

You can reduce the amount of code by using the for cursor construct, you had to go through a number of steps
to get the data define variables, define the cursor, open the cursor, fetch the data in a loop, exit the loop then
close the cursor, with the for construct all you have to do is define the cursor.

create or replace procedure test_cursor_proc_2


IS
cursor test_cursor IS select fname, lname from employees;
BEGIN
FOR name_rec IN test_cursor
example
loop
dbms_output.put_line( 'First Name: ' || name_rec.first_name || 'Surname: ' ||
name_rec.last_name);
end loop;
END;

Implicit Cursor
PL/SQL and SQL -3-

You can use the PL/SQL statement instead of a cursor, Oracle will create a implicit cursor that operates behind
the scenes like a explicit cursor.

create or replace procedure test_cursor_proc2_3


IS
BEGIN
FOR name_rec IN select fname, lname from employees;
loop
dbms_output.put_line( 'First Name: ' || name_rec.first_name || 'Surname: ' ||
example
name_rec.last_name);
end loop;
END;

Note: the select statement will use a implicit cursor, the %ISOPEN will return false since there is
no explicit cursor open.

REF cursors

A ref cursor allows you to pass a cursor reference from one PL/SQL program unit to another, you can create a
variable that will recieve a cursor and enable access to it.

create or replace procedure test_cursor_proc_3(p_cursor OUT sys_refcursor)


IS
BEGIN
FOR p_cursor IN select fname, lname from employees;
END;

create or replace procedure test_cursor_proc_3(p_cursor OUT sys_refcursor)


Example IS
type p_cursor is ref cursor return employees%ROWTYPE;
BEGIN
FOR p_cursor IN select fname, lname from employees;
END;

Note: the top example is a weakly typed ref cursor, the bottom type is a strongly typed ref
cursor.

Collections

You may want to fetch a entire dataset into an array like structure, PL/SQL has a class of variables that will let
yoy accomplish this is called collections. Although a collection is a single dimensional array you can simulate
multidimensional arrays by creating a collection with a data type that is another collection.

There are three types of collections

• associative arrays
• nested tables
PL/SQL and SQL -4-

• variable arrays

Associate Arrays are collections that are indexed by a value, arrays can be indexed by binary integer,
pls_integer, postive, natural or varchar2. You cannot store an associative array directly in the database, so you
need logic to store and retrieve the values in this type of collection with the database., it also cannot be use in
SQL.

DECLARE
TYPE a_char is table of varchar2(10) index by binary_integer
v_char_data a_char_data;
BEGIN
v_char_data.extend;
associative array v_char_data(1) := 'ABC'; # can have up to 10 chacaters as stated above
example v_char_data(2) := 'DEF';

for i in v_char_data.first .. v_char_data.last


loop
dbms_output.put_line(v_char_data(i));
end loop;

Nested Tables use sequential integers as the index to the collection, a nested table can have nonconsecutive
numbers as index, creating what is known as a sparse index.

DECLARE
TYPE a_char_data IS table of varchar2(10);
v_char_data a_char_data := a_char_data(); # calls the nested table constructor
BEGIN
v_char_data.extend;
v_char_data(1) := 'ABC'; # can have up to 10 chacaters as stated above
v_char_data.extend;
v_char_data(2) := 'DEF';
Nested table
example
for i in v_char_data.first .. v_char_data.last
loop
dbms_output.put_line(v_char_data(i));
end loop;
end;

Note: extend is a method that adds a new empty element to a nested table, this must be called
first.

Variable Array (Varrays) alos use integers to index the collection and can be stored in a database column. They
are generally used when you how what maximum size you need.

VArray example DECLARE


TYPE a_char_data IS VARRAY(5) of varchar2(10);
v_char_data a_char_data := a_char_data(); # calls the nested table constructor
PL/SQL and SQL -5-

BEGIN
v_char_data.extend;
v_char_data(1) := 'ABC'; # can have up to 10 chacaters as stated above
v_char_data.extend;
v_char_data(2) := 'DEF';

for i in v_char_data.first .. v_char_data.last


loop
dbms_output.put_line(v_char_data(i));
end loop;
end;

There are a number of operations that you can perform on a collection

EXISTS check to see if an element in a collection exists collection.exists(index)


COUNT returns the number of elements collection.count
LIMIT returns the maximum number of entries in a VARRAY collection.limit
FIRST returns the first element collection.first
LAST returns the last element collection.last
NEXT returns the next element in the collection collection.next
PRIOR returns previous element in a collection collection.prior
collection.extend
EXTEND extends the number of elements in a collection collection.extend(n)
collection.extend(n, I)
collection.trim
TRIM removes elements from the end of a collection
collection.trim(n)
collection.delete
DELETE removes elements from a collection collection.delete(n)
collection.delete(m,n)

The table below summaries the differences between the above collections

Associate Array Nested Table VARRAY


index type Number or String Number Number
fixed size declared No No Yes
spare index allowed Yes Yes No
store in database No Yes Yes
access individual elements in stored collection n/a Yes No

Bulk Collect operations

Executng SQL statements in programs causes a context switch between the PL/SQL and SQL engines, too many
context switches and performance degrades, to reduce context switches we use bulk collect which lets us
PL/SQL and SQL -6-

tranfers rows between SQL and PL/SQL as collections. Normally developers usually tend to use the cursor for
loops method for precessing data, they declare a cursor, open it, fetch from it row by row in a loop and process
the row they fetched.

DECLARE
cursor test_cursor select object_name from t_all_objects;
type cl_type is table of test_cursor%rowtype;
recl cl_type ;
Bulk collect example
BEGIN
open test_cursor;
fetch test_cursor bulk collect into recl;
END;
DECLARE
cursor test_cursor select object_name from t_all_objects;
type cl_type is table of test_cursor%rowtype;
recl cl_type ;
BEGIN
open test_cursor;
loop
Bulk collect example
fetch test_cursor bulk collect into recl limit 2000;
(limit rows)
for i in 1 .. recl.count
loop
null;
end loop;
exit when test_cursor%notfound;
end loop;
END;

Forall statement

The forall statement basically does the same as the bulk collect statement, the construct packages up multiple
write statements and sends them off to the oracle database in a single message thus reducing overall
performance of the whole operation.

indices of clause allows bulk operation on a sparse collection (where elements have been deleted) by removing
the reference to specific elements.

values of clause alows values of one collection to be used as index pointers to another collection.

forall <index> IN lower_bound .. upper_bound


forall example
sql_statement;
forall example forall <index> IN lower_bound .. upper_bound save exceptions
(exception capature) sql_statement;
forall example forall <index> INDICES OF lower_bound .. upper_bound
(indices of) sql_statement;
forall example forall <index> VALUES OF lower_bound .. upper_bound
PL/SQL and SQL -7-

(values of) sql_statement;

You might also like