Upload
ezra-owen
View
247
Download
1
Embed Size (px)
Citation preview
Lecture 4
Introduction to PL/SQL Procedures & Cursors
Overview
Overview of PL/SQL Development of a coded block Interacting with an Oracle Database Controlling PL/SQL process flow Cursor handling
Embedding SQL
SQL is not functionally complete Lacks the full facilities of a programming language
variables, flow of control etc.
All DBMSs top up functionality by embedding SQL in a procedural language
But details vary from one DBMS to another. However, procedures and functions can be ported
between systems.
PL/SQL - Introduction
An Oracle-specific procedural extension to SQL, allowing for modularity, variable declaration, loops and logical constructs.
Allows for advanced error handling. Communicates natively with other Oracle
database objects. Managed centrally within the Oracle
database.
Why use PL/SQL?
Manage business rules – through middle layer application logic.
Generate code for triggers. Generate code for the user interface. Enable database-centric client/server
applications.
Centralised vs. Decentralised
Common copy of executed code – one copy to maintain
Multiple copies of executable code on the decentralised system – multiple copies to maintain leading to increase difficulty in maintaining the system
Begin
:
End;Server
Begin
:
End;
Begin
:
End;
Begin
:
End;
Server
Advantages of using PL/SQL to access Oracle PL/SQL is managed centrally within the database. Code is managed by the DBA, and execution
privileges are managed in the same way as with other objects.
PL/SQL objects are first-class Oracle DB objects. Easy to read:
with modularity features and error handling.
Centralised Control
Enables the DBA to: specify rules in one place (as a procedure,
function, trigger or package in PL/SQL); force user access through the predefined
PL/SQL, so users cannot write their own procedural code and use this instead e.g. define security privileges giving users access to
table(s) only through a particular procedure.
Using PL/SQL as a Programming Language
Permits all “flow of control” operations of standard programming languages, e.g. Jumps GOTO ConditionsIF-THEN-END IF;
IF-THEN-ELSE-END IF Loops LOOP-EXIT;
WHEN-END LOOP;FOR-END LOOP;WHILE-END LOOP
Allows extraction of data into variables and its subsequent manipulation.
Modules in PL/SQL
There are 4 types of modules in PL/SQL Procedure – a series of statements which may or
may not return a value. Function – a series of statements which must
return a single value. Trigger – a series of statements which is executed
after an event has triggered a condition. Package – a collection of procedures and
functions which has 2 parts: a listing and a body.
Use of Data Types Number – used to store any number. Char(size) & varchar2(size) e.g. char(10) –
used to store alphanumerical text strings; the char data type will pad the value stored to the full length declared.
Date – used to store dates and times. Long – used to store large blocks of text up
to 2 gigabytes in length (limited operations)
Non-DB Data Types
DEC, DECIMAL, REAL, INTEGER, INT – these are numerical data types that are a subset of number.
Binary_integer – binary format for number type but can not be stored in database unless converted first.
Character – same as char. Boolean – true/false value. Table/record – tables can be used to store the equivalent
of an array while records store the variables with composite data types.
SQL Scripts A set of commands to run in sequence. Stored as a text file (e.g. using Notepad) on disk
and not in the data dictionary. It is accessed by its file name using @ or Start.
Script called:
Create_lecturer_copy.sql
Executed by:
SQL> @U:\create_lecturer_copy
The SQL Procedure
A block of SQL statements stored in the Data Dictionary and called by applications.
Satisfies frequently-used or critical application logic. When called, all code within the procedure is executed
(unlike packages). Action takes place on the server, not the client. Does not (normally) return a value to the calling program. Not available in Oracle 6 or older. Aids security as DBA may grant access to procedures
rather than tables, therefore some users cannot access tables except through a procedure.
Building a Procedure: Contents
1. CREATE OR REPLACE command;
2. Object to be created;
3. Name of object;
4. Any variables accessed or imported;
5. Local variables declared;
6. Code block enclosed by BEGIN … END;
Create or replace procedure inflation_rise (inf_rate in number)
Begin
update employee
set salary = salary + (salary * inf_rate / 100);
commit;
End;
1. Create or replace command
2. Object to be created
3. Name of object
4. Any variables accessed or imported
5. Declared local variables
6. Code
This procedure is called inflation_rise and uses a variable accessed as inf_rate which is a number, this is passed in when the procedure is used. It simply updates the salary by the rate of inflation.
Compiling and Executing Procedures Like any program the code needs to be compiled. @inflation_rise
compiles the procedure from a file with this name; makes it available to the data base.
Execute inflation_rise executes the procedure.
Remember to re-compile a procedure after editing.
For ease of use, it is best to write procedures in Notepad, then they can be easily edited and you have a back-up copy.
ExampleCREATE OR REPLACE PROCEDURE validate_customer (v_cust VARCHAR) AS
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count
FROM CUSTOMER
WHERE CUST_CODE = v_cust;
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE(‘customer valid’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘customer not recognised’);
END IF;
END;
SQL Code Block
Variable passed into procedure
Local variable used by procedure
Cursors in SQL Enables users to loop round a selection of
data. Stores data select from a query in a temp
area for use when opened. Use complex actions which would not be
feasible in standard SQL selection queries
Declaring Cursors Declared as a variable in the same way as
standard variables. Identified as cursor type. SQL included, e.g.
Cursor cur_emp is
Select emp_id, surname ‘name’, grade, salary
From employee
Where regrade is true;
Cursors A cursor is a temporary store of data. The data is populated when the cursor is opened. Once opened, the data must be moved from the
temporary area to a local variable to be used by the program. These variables must be populated in the same order that the data is held in the cursor.
The data set is looped round till an exit clause is reached.
Current rowCurrent rowCursor
Active setActive set
7369 SMITH CLERK
7566 JONES MANAGER
7788 SCOTT ANALYST
7876 ADAMS CLERK
7902 FORD ANALYST
Cursor FunctionsCursor Functions
Controlling the CursorControlling the Cursor
• Create a Create a named named SQL areaSQL area
DECLAREDECLAREDECLAREDECLARE
• Identify Identify the active the active setset
OPENOPENOPENOPEN
• Load the Load the current current row into row into variablesvariables
FETCHFETCHFETCHFETCH
• Test for Test for existing existing rowsrows
EMPTY?
• Return to Return to FETCH if FETCH if rows rows foundfound
NoNo
• Release Release the active the active setset
CLOSECLOSECLOSECLOSEYesYes
Controlling the Cursor…Controlling the Cursor…Open the cursor.Open the cursor.
CursorCursor
PointerPointer
Fetch a row from the cursor.Fetch a row from the cursor.
CursorCursor
PointerPointer
Continue until empty.Continue until empty.
CursorCursor
PointerPointer
Close the cursor.Close the cursor.
CursorCursor
Cursor AttributesCursor Attributes
Attribute Type Description
%ISOPEN Boolean Evaluates to TRUE if the cursor is open
%NOTFOUND Boolean Evaluates to TRUE if the most recent fetch does not return a row
%FOUND Boolean Evaluates to TRUE if the mostrecent fetch returns a row; logicalcomplement of %NOTFOUND
%ROWCOUNT Number Evaluates to the total number of rows returned so far
To obtain status information about a cursor.
Create or replace procedure proc_test as
v_empid number;
Cursor cur_sample isSelect empid from employee where grade > 4;
Beginopen cur_sample;loopfetch cur_sample into v_empid;exit when cur_sample%notfound; update employee
set salary = salary + 500where empid = v_empid;
end loop;End;
Open cursor for use.
Loops round each value
returned by the cursor
Place the value from the cursor into the variable v_empid
Stop when no more records are found
25463
12245
55983
12524
98543
Data returned by cursor
Declare Cursor
Notepad file called:
Create_procedures.sql
1) Open SQL*Plus and logon
2) At the prompt enter:
@create_procedures
You will get a prompt which should say ‘procedure created’ otherwise use
SHOW ERRORS to view errors in the code.
3) To run the procedure enter:
Execute proc_test
4) If you check your data you should now find that the procedure has run successfully
Use of conditions IF statements can be used
If <condition> Then…..
End if;
E.g.
Remember to end the IF statement Use of indented code will make it easier to debug!
. . .IF v_ename = 'MILLER' THEN v_job := 'SALESMAN'; v_deptno := 35; v_new_comm := sal * 0.20; END IF;. . .
. . .IF v_ename = 'MILLER' THEN v_job := 'SALESMAN'; v_deptno := 35; v_new_comm := sal * 0.20; END IF;. . .
The %ISOPEN Attribute Can fetch rows only when the cursor is open. Use the %ISOPEN cursor attribute before
performing a fetch to test whether the cursor is open.
Example
IF NOT cur_sample%ISOPEN THENOPEN cur_sample;
END IF;LOOP FETCH cur_sample...
IF NOT cur_sample%ISOPEN THENOPEN cur_sample;
END IF;LOOP FETCH cur_sample...
DECLARE CURSOR emp_cursor IS SELECT empno, ename FROM emp; emp_record emp_cursor%ROWTYPE;BEGIN OPEN emp_cursor; LOOP FETCH emp_cursor INTO emp_record; ...
DECLARE CURSOR emp_cursor IS SELECT empno, ename FROM emp; emp_record emp_cursor%ROWTYPE;BEGIN OPEN emp_cursor; LOOP FETCH emp_cursor INTO emp_record; ...
Cursors and RecordsCursors and RecordsProcess the rows of the active set conveniently by fetching values into a PL/SQL RECORD.Example
Cursor FOR LoopsCursor FOR Loops
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;
The cursor FOR loop is a shortcut to process cursors.Syntax
Implicitly opens, fetches, and closes cursor.The record is implicitly declared.
Cursor FOR Loops: An ExampleCursor FOR Loops: An Example
Retrieve employees one by one until no more areRetrieve employees one by one until no more areleft:left:
DECLARE CURSOR emp_cursor IS SELECT ename, deptno FROM emp;BEGIN FOR emp_record IN emp_cursor LOOP -- implicit open and implicit fetch occur IF emp_record.deptno = 30 THEN ... END LOOP; -- implicit close occursEND;
DECLARE CURSOR emp_cursor IS SELECT ename, deptno FROM emp;BEGIN FOR emp_record IN emp_cursor LOOP -- implicit open and implicit fetch occur IF emp_record.deptno = 30 THEN ... END LOOP; -- implicit close occursEND;