Introduction To PL
Introduction To PL
pl/sql programming
INTRODUCTION TO PL/SQL
CHAPTER I
PL/SQL ENGINE, BLOCKS, DATATYPES
Terminology
1/117
Oracle
pl/sql programming
The following Terminology will arm you with the technical jargon to get through
this chapter.
2/117
Oracle
pl/sql programming
A stored object is a PL/SQL program that is saved in the database and
may be shared and used by many developers and end users. Procedures,
packages, functions, and triggers are all examples of stored objects.
3/117
Oracle
pl/sql programming
ORACLE DATABASE
INTEGRATED SQL
INTEGRATED
ENGINE SQL
ENGINE
External
Program
calls
PL/SQL
Stored
Program
PL/SQL
PL/SQL
Engine
Engine
SQL
ENGINE
SQL
ENGINE
DATABASE
4/117
Oracle
pl/sql programming
SQL *Plus
Oracle Enterprise Manager
Oracle precompilers (such as Pro *C, Pro *COBOL, etc.)
Oracle Call Interface (OCI)
Server Manager
Oracle 9i Application Server
Java Virtual Machine (JVM)
As you can see, PL/SQL is well established within most of
the Oracle9i line of products. You may now have some background in the
Pl/SQL architecture. Lets discover the basics of the language.
PL/SQL CHARACTER SET
As with all programming languages, there are characters
that you use to write your programs. Each language has its own rules and
restrictions when it comes to the valid characters. In the following
sections, we will learn the following:
Supported Characters
When programming in PL/SQL, you may only use characters as
defined here:
Oracle
pl/sql programming
Meaning
**
*, /
Exponent
Multiplication,
division
+, - , ||
Addition, subtraction,
concatenation.
Meaning
Equal
Not equal
Greater than
Less than
Greater than or equal
Less than or equal
6/117
Oracle
pl/sql programming
PL/SQL STRUCTURE
The structure used in all of PL/SQL is the foundation for all of
the language. When you master it, you will be able to move forward, but
if you do not take the time to get this first step right, your journey will be
difficult. Actually, it is easy, Lets look at the structure that all of your
Pl/SQL programs will have.
You will have areas for program parameters (used to pass values from
outside a program to the program), internal variables, the main program
code and logic, and then some ways to handle things when they go
wrong.
PL/SQL BLOCK STRUCTURE
A basic PL/SQL block of code can contain up to three parts. The order in
which the sections of the blocks are written is shown below:Section
Description
Inclusion
Declarative
Optional
7/117
Oracle
Note:
pl/sql programming
Executable
Mandatory
Exception
Handling
Optional
8/117
Oracle
pl/sql programming
PL/SQL block structure
DECLARE -Optional
-Variables,constants,
cursors,user-defined exceptions
BEGIN -Mandatory
-SQL Statements
-PL/SQL control statements
EXCEPTION -Optional
-Actions to perform when errors occur.
END; - Mandatory
Description
Unnamed PL/SQL block
that is embedded within
9/117
Availability
All PL/SQL environments.
Oracle
Stored Procedure or
Function
Application Procedure or
Function
Package
Database Trigger
Application Trigger
pl/sql programming
an application or is
issued interactively.
Named PL/SQL block
that can accept
parameters and can be
invoked repeatedly.
Named PL/SQL block
that can accept
parameters and can be
invoked repeatedly.
Named PL/SQL module
that groups together
related procedures,
functions, and identifiers.
PL/SQL block that is
associated with a
database table and is
fired automatically.
PL/SQL block that is
associated with an
application even and it
fired automatically.
Oracle
pl/sql programming
BLOCK TYPES
Anonymous
[DECLARE]
BEGIN
--statements;
Procedure
Function
PROCEDURE name
IS
FUNCTION name
IS
BEGIN
BEGIN
--statements
--statements
RETURN value;
[EXCEPTION]
[EXCEPTION]
[EXCEPTION]
END;
END;
END;
11/117
Oracle
pl/sql programming
NOT NULL
EXPR
Guidelines
Name the identifier according to the same rules used for SQL objects
You can use naming conventions, for example v_name to represent a
variable, and c_name to represent a constant.
12/117
Oracle
pl/sql programming
You have the option of assigning an initial Value to variables, unless they are
NOT NULL.
Initialize the variable to an expression with the assignment operator (:=) or
equivalently, with the DEFAULT reserved word: otherwise, variables are
initialized to NULL by default.
Declare at most one identifier per line.
Number
Character
date and time
Boolean
Datatype
BINARY-INTEGER
NUMBER(Precision-scale)
CHAR (Maximumlength)
LONG
VARCHAR2(maximum-length)
DATE
BOOLEAN
Description
Base type for integers between
2147483647 and 2147483647.
Base type for fixed and floating point
numbers.
Base type for fixed length character data
up to 32767 bytes. If you do not specify
a maximum length, the default length is
set to 1.
Base type for variable length character
data upto 32760 bytes.
Base type for variable length character
data up to 32767 bytes.
Base type for dates and times.
Base type that stores one of three
possible values used for logical
13/117
Oracle
pl/sql programming
calculations: TRUE,FALSE, or NULL.
Scalar Variable Declarations: Examples
V_gender
V_count
V_total_sal
V_order_date
C_tax_rate
V_valid
CHAR(1);
BINARY_INTEGER := 0;
NUMBER(9,2) := 0;
DATE := SYSDATE + 7;
CONSTANT NUMBER(3,2) := 8.25;
BOOLEAN NOT NULL := TRUE;
- BINARY-INTEGER :=0;
3. Declare a variable to accumulate the total salary for a department and initialize
the variable to 0
V_total_sal
4. Declare a variable to store the ship date of an order, and initialize the variable
to one week from today.
V_order_date DATE := SYSDATE + 7;
5. Declare a constant for the tax rate, which never changes throughout the
PL/SQL block.
C_tax_rate CONSTANT NUMBER (3,2) := 8.25;
14/117
Oracle
pl/sql programming
Oracle
pl/sql programming
in place of the datatype required in the variable declaration, prefix it with the
database table and column names. If referring to a previously declared variable,
prefix the variable name to the attribute.
PL/SQL determines the datatype and size of the variable when
the block is compiled. So the variable is always compatiable with the database
column or identifier used to populate the variable.
Advantages of Using the %TYPE Attribute
The datatype of the underlying database column may be unknown.
The datatype of the underlying database column may change at runtime.
Examples
1. Declare variables to store the first and last names for an employee.
DECLARE
V_last_name
V_first_name
s_emp.lastname%TYPE;
s_emp.first_name%TYPE;
DECLARE
V_balance
NUMBER (7,2);
V_minimum_balance v_balance%TYPE := 10;
A NOT NULL column constraint does not apply to variables
declared using %TYPE. Therefore, if you declare a
variable using the % TYPE attribute, using a database
column defined as NOT NULL, you can assign the NULL
value to the variable.
DECLARING COMPOSITE DATATYPES
Declaring Records with the %ROWTYPE Attribute
16/117
Oracle
pl/sql programming
The % ROWTYPE Attribute
Declare a variable according to a collection of columns in a
database table or view.
Prefix %ROWTYPE with the database table.
Fields within the RECORD take their names and datatypes from
the columns of the table or view.
You declare records in the DECLARE section of a block, along with the
other types of variables you have seen.
Dept_record
Emp_record
DECLARE
s_dept%ROWTYPE;
s_emp%ROWTYPE;
17/117
Oracle
pl/sql programming
This declaration creates a record with the same field names and field
datatypes as a row in a table. DEPT_RECORD is a record. The fields
are: DEPT_RECORD.ID, DEPT_RECORD.NAME and
DEPT_RECORD.REGION_ID
Referencing Non-PL/SQL Variables
18/117
Oracle
pl/sql programming
CHAPTER 2
CONTROL STRUCTURES, EXCEPTIONS, TRIGGERS
AND CURSOR
CONTROL STRUCTURES
At the heart of any programming language are its control structures.
Since Programs are written to handle a number of different situations, the
manner in which different conditions are detected and dealt with is the biggest
part of program control. Various types of control structures are used for this
purpose, including
If logic structures
Case expressions
Looping structures
Program control is governed by the status of variables and the data
that is read from and written to the database. As an example, picture yourself
going into the drivers license office to renew your drivers license. When you
enter the officer, you are presented with a number of directional signs. One sign
reads Driver Testing ; for this, you go to the second floor. Another sign tells you
that License Renewals is one the third floor. You are here for a renewal, so you
head up to the third floor. Once you arrive in the renewal office, you are once
again faced with some new choices. Now you have to decide whether you are
going to pay by cash or credit card. Cash payments are being accepted to the
right, and credit cards are to the left. You see that you have enough cash, and
you head to the payment wicket on the right. Let us look at Table below and see
how our program control influenced your choices.
next steps
Oracle
pl/sql programming
10
cash payment wicket
12
11
credit card payment
12
receive new license
13
13
go home leave building
-------------------------------------------------------------------------------------------------TABLE- Program Control Decision Matrix
IF Logic Structures
When you are writing computer programs, situations present
themselves in which you must test a condition. When you ask a question
in your program, you are usually presented with one of two answers; it
may be true or it may be false. Computer programs are black and white;
in computer logic, there can only be true or false answers to your
questions, no maybe. PL/SQL provides you with three distinctive if logic
structures that allows you to test for true and false conditions. In everyday
life we are presented with decisions that we need to make; the following
sections will show you how to do it using PL/SQL.
IF - THEN
You use the if-then construct to test the simplest type of
condition. If the condition evaluates to true, then one or more lines of
program code will be executed. If the condition evaluates as false, then
no action is taken. The following code snippet illustrates how this is
performed with a PL/SQL program.
IF I_date > 11-APR-03 then
I_salary := I_salary * 1.15;
- - Increase salary by 15%
END IF:
NOTE:
20/117
Oracle
pl/sql programming
In this case, if the value of the variable I_date is greater than
11th of April 2003, then the salary will be increased by 15 percent . This
statement may also be restated using the following statement.
IF not (I_date <= 11 APR-03) then
I_salary := I_salary *1.15;
-- Increase salary by 15%
END IF;
Also, you nest IF _ THEN statement to increase the power
of your statements. Let us add a condition to limit who gets the raise:
IF I_date > 11-Apr-03 then
IF I_last _name = PAKMAN then
I_salary := 1-salary *1.15 ;
-- Increase salary by 15%
END IF;
END IF:
Now, not only must the date be greater than the 11th of April ,
2003, but also your last name must be equal to Pakman in order to get the
raise. This a method that we use to make sure human resource programs
give programmers a raise every year.
What you should also notice in this code is that there are now two end if
statements. This is a required construct, since you must always pair an if
statement with an end if; so if you are going to have nested if statements,
you must ensure that each is paired with a matching end if;
NOTE
IF - THEN ELSE
The if-then-else construct is similar to the simple if-then
construct. The difference is that when the condition executes as false , the
program statements that follow the else statement are executed. The
following code illulstrated this logic within PL/SQL.
IF I_date > 11-APR-03 then
I_salary := I_salary *1.15 ;
-- Increase salary by 15%
ELSE
I_salary := I_salary *1.05 ;
21/117
Oracle
pl/sql programming
--Increase salary by 5%
END IF;
In the preceding code listing, you see the condition that if the
date is greater than the 11th of april, 2003, you will get a 15 percent salary
increase. However, when the date is less than or equal to this date, you
will only receive a 5 percent increase.
As with the simple if-then construct, you may nest the ifthen-else construct. Let us look at how this might appear in our PL/SQL
program:
IF I_date > 11-Apr-03 then
IF I_last_name = PAKMAN then
I_salary := I_salary *1.15;
-- Increase salary by 15%
ELSE
I_salary := I_salary *1.10;
-- Increase salary by 10%
END IF;
ELSE
I_salary := I_salary *1.05;
-- Increase salary by 5%
END IF;
NOTE:
- Only one else statement is allowed within every if statement construct,
and there is no semicolon(;) on the line starting with else.
IF THEN - ELSIF
The final if construct that we will show you is if-then-elsif. In
this case, you provide yourself with the option to test another condition
when the first condition is evaluated as false. When you want to test for
more than one condition without using nested if statements, this is the type
of statement that you might use.
IF I_last__name = PAKMAN then
I_salary := I_salary *1.15;
-- Increase salary by 15%
ELSIF I_last_name = ASTROFF then
I_salary := I_salary *1.10;
22/117
Oracle
pl/sql programming
-- Increase salary by 10%
ELSE
I_salary := I_salary *1.05;
-- Increase salary by 5%
END IF;
In the preceding statement, if your last name is Pakman, you
get a 15 percent raise; if it is Astroff, you get 10 percent; and the rest of us
get only a 5 per cent raise. There is no limit to the number of elsif
conditions that you may use within this construct. The following shows
you an example of using multiple elsif statement within the construct.
IF I_city = OTTAWA then
L_team_name := SENATORS;
ELSIF I_city = LOS ANGELS then
L_team_name := KINGS;
ELSIF I_city = NEW YORK then
L_team _name := RANGERS;
ELSIF I_city = TORONTO then
L_team_name := MAPLE LEAFS;
END IF;
NOTE:
There is no matching END IF statement for each elsif. Only a single
END IF is required within this construct.
When writing your PL/SQL program, use indentation to simplify the
reading of the program, as in the code segments shown here. As a rule ,
you should line up each if-then-else statement, and indent the program
code that lies between each of these words.
CASE EXPRESSIONS
The next logical step from the if statement is the case
statement. The case statement, which was introduced with Oracle 9i, is
an evolution in logical control. It differs from the if-then-else constructs in
that you now can use a simple structure to logically select from a list of
values. More important, it may be used to set the value of a variable. Let
us look at how this may be done. First, let us look at the format:
23/117
Oracle
pl/sql programming
CASE variable
WHEN expressional then value 1
WHEN expression 2 then value 2
WHEN expression 3 then value 3
WHEN expression 4 then value 4
ELSE value 5
END;
SQL>run
1 DECLARE
2 val varchar2(100) ;
3 city varchar2 (20) := TORONTO;
4 BEGIN
5 val := CASE city
6 WHEN TORONTO then RAPTORS
7 WHEN LOS ANGELS then LAKERS
8 WHEN BOSTON then CELTICS
9 WHEN CHICAGO then BULLS
10 ELSE NO TEAM
11 END;
12
13 dbms_ouput.put_line (val);--output to the screen
14 * end;
15 RAPTORS
PL/SQL procedure successfully completed.
NOTE:
Oracle
pl/sql programming
Remember that once Oracle 9i reaches a value in the case statement that
meets the condition, the processing of the case statement will stop.
LOOPS
Loops are control structures that allow you to repeat a set of
commands until you decide that it is time to stop the looping.
Generally, the format that all loops take is the flowing:
LOOP
Executable statements;
END LOOP;
Each time the loop is executed, the statements within the loop are
executed, and then the program return to the top of the loop structure to
do it all over again. However, if you ever want this processing to stop,
you will need to learn about the EXIT statement.
The exist statement allows you to stop executing within a loop
without a condition. It will then pass control back to the program and will
continue on after the loop statements.
The following is how to get out of a tight loop:
LOOP
IF I_batting_average <= 300 then EXIT;
ELSE
L_decision := STAY IN MAJORS;
END IF;
END LOOP;
There are many other kinds of loops that provide more
control over looping. Each has its uses in PL/SQL programming, and each
should be learned so that you have maximum flexibility in your
programming needs.
25/117
Oracle
pl/sql programming
The while Loop
The while loop will continue to execute as long as the condition that you
have defined continues to be true. If the condition becomes false, then
you exit the loop. Let us look at an example.
WHILE I_sales_total < 100000 LOOP
SELECT sales_amount INTO
I_sale_amount
FROM daily_sales;
I_sales_total := I_sales_total + I_sale_amount;
END LOOP;
Although you may use the exist command to do the same thing.
It is better form to use the while expression.
26/117
Oracle
pl/sql programming
use the values in the loop, you will discover that they are now
set to values between 1 and 10.
-
DECLARE
I_counter number;
BEGIN
FOR I_counter IN REVERSE 1..5
LOOP
Dbms_output.put_line (I_counter);
END LOOP;
End;
/
5
4
3
2
1
PL/SQL procedure successfully completed.
Now you can see how easy it is to use simple loops, but loops have
much more power. Using loops like the while loop or the for loop allows you to
use variables instead of hard coded values. This gives you the greatest possible
flexibility because you can have the database or external data provide you with
the limits within your loop. Let us look at how this might work. In the following
example, we select the number of employees in our employee table, and then
show how the counter counts from 1 to the number of employees in our small
company.
SQL>run
1 DECLARE
2 I_emp_count number;
3 i number ; -- We will use this as our counter
4
BEGIN
5
select the number of employees in the
I_emp_count variable
6 Select count (*) into I_emp_count from employees;
7
8
FOR i IN 1 .. I_emp_count LOOP
27/117
--
Oracle
pl/sql programming
9 dbms_output.put_line (Employee || i);
10
END LOOP;
11 *END;
Employee 1
Employee 2
Employee 3
Employee 4
Employee 5
Employee 6
PL/SQL procedure successfully completed.
- As you might have guessed, we have six employees in our company. (It
may be small, but it is very good.) The important point is that you may use
variables in your loops. The other line that you may have noticed is the select
statement contained in this PL/SQL block. You might be thinking, what are
they talking about and where did this come from ? Well, we have not told you
about select statements in your Pl/SQL programs, but this seems like a
perfect time to talk about SQL in your PL/SQL programs.
SQL in Your PL/SQL Programs
We have looked at a lot of structure up until now. You should know that a
PL/SQL program will always have a BEGIN and END. It may have variables ,
loops, or logic control, but your next question must be wheres the best ?
What gives PL/SQL its beef is SQL. Since you have all these CONTROL
structures, you need to use them in conjunction with information.You may
want the information
so that you can create a report, update data, create
new data,and delete old data, or perform just about any other function that
you can think of. It is very important for you to see how you can integrate
data into PL/SQL code. Without data, PL/SQL is just PL.
28/117
Oracle
pl/sql programming
EXCEPTIONS
INTRODUCTION
When you execute PL/SQL program, you may encounter errors, that stop
the program. Any well-written program must have the ability to handle such
errors intelligently and recover from them , if possible. PL/SQL implements error
handling via exceptions and Exception Handlers which can be associated with
oracle errors or with user defined errors. In this chapter, we wll discuss the
types of exceptions, how exceptions are raised and handled, association of
exceptions with ORACLE error and the rule of the exception propogation. It also
provides the guidelines on using exceptions.
We already know how PL/SQL is based on the ADA language. One of the
features of ADA that is incorporated into PL/SQL is the exception mechanism,
that makes your programs robust and able to deal with both unexpected and
expected errors during execution.
What kinds of error can occur in a PL/SQL Program ?
Errors can be classified as compile-time and run-time errors. Compiletime errors are reported by PL/SQL compiler interactivelty & you have to correct
them. Without correcting them PL/SQL wll not run at all.
So exceptions are designed for runtime error handling only, rather than
compile time error handling.
WHAT IS EXCEPTION?
An exception is an identifier in PL/SQL which is raised when an error occurs,
during the execution of a block. This terminates its main body of actions and
transfers control to a separate program called exception handler , which specifies
the final action to be performed. This separates the error handling from the rest
of the program which makes the logic of the program, easier to understand.
This also ensures that all errors will be trapped.
In a language (such as C) that does not use the exception model for error
handling , you must explicitly insert error handling code in order to ensure that
your program can handle errors , in all cases.
For example
Int x,y,z;
Function(x); /* function call, passing x as an argument */
29/117
Oracle
pl/sql programming
TRAPPING EXCEPTIONS:
Generally exceptions are declared in the declarative section of the block,
raised in the executable section and handled in the exception section.
PL/SQL provides a set of system defined exceptions and allows you to
add user defined exceptions.
There are 3 types of exceptions. They are as follows.
30/117
Oracle
pl/sql programming
1.
31/117
Oracle
pl/sql programming
SYNTAX:
RAISE exception_name;
32/117
Oracle
pl/sql programming
Where exception_name is the name of the previously defined
exception.
3.
HANDLING EXCEPTIONS:
Reference the declared exception within
the corresponding exception handling routine using WHEN CLAUSE.
WHEN exception_name THEN
Statements;
Where exception_name is the name of the exception declared in the
declarative section and raised in the exevutable section.
EXAMPLE FOR USER DEFINED EXCEPTION:
DECLARE
e_invalid_staffno EXCEPTION;
BEGIN
IF &&p_staffno IS NULL OR
(TO_NUMBER (&p_staffno)
NOT BETWEEN 1000 ND 9999
THEN
RAISE e_invalid_staffno;
ELSE
INSERT INTO emp_data (staffno,emp_name, deptno)
VALUES (&p_staffno, &p_name, &p_deptno);
INSERT INTO emp_sal (staffno)
VALUES (&p_staffno);
END IF;
EXCEPTION
WHEN e_invalid _staffno THEN
INSERT INTO MESSAGE
VALUES (INVALID STAFF NUMBER, Staff number: || &p_staffno ||
must be between 1001 and 9999 );
END;
/
EXPLANATION: In the above example e_invalid_staffno is defined as an
exception in the declarative section by the user. In the executable section the
verification of staff number i.e. whether it is within the range 1001 -9999 is
33/117
Oracle
pl/sql programming
NUMBER (2);
CHAR (4);
varchar2(25);
varchar2(5);
CHAR(3);
BEGIN
SELECT TO_NUMBER(staff no) -1000 as SL_NO, staffno,
Emp_name,desgn, hq
INTO v_sl,v_staffno, v_desgn, v_hq
FROM emp_data
WHERE staffno = ABCD;
INSERTINTO message
VALUES (to_char (v_sl) || - || v_staffno,
v_name || || desgn || - ||v_hq);
EXCEPTION
WHEN INVALID_NUMBER THEN
INSERT INTO Message
VALUES (invalid number, There is a wrong character value in the staff
number);
END;
/
Now execute the program and see the resultas follows:
SQL>SELECT *FROM MESSAGE;
OUTPUT:
INVALID NUMBER There is a wrong character value in the staff number.
34/117
Oracle
pl/sql programming
Explnation:
The staffno ABCD is converted to a number by the TO_NUMBER
function in the SQL statement. But since abcd cannot be converted
into a number, the exception INVALID_NUMBER is raised and action
is taken accordingly.
Example for DUP_VAL_ON_INDEX:
DECLARE
BEGIN
INSERT INTO emp_data (staffno, emp_name, deptno)
VALUES (&p_staffno, &P_name, &p_deptno);
Insert into EMP_SAL(staffno)
Values (&p_staffno);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
INSERT INTO MESSAGE
VALUES(DUP_VAL_ON_INDEX,
STAFFNO || &p_sattno || already exists);
END;
EXPLANATION:
When you try to insert a new row with the existing staff no,
DUP_VAL_ON_INDEX is raised and action is taken accordingly.
Example for NO_DATA_FOUND AND TOO_MANY_ROWS:
DECLARE
V_basic
V_name
V_desgn
emp_sal.basic%TYPE;
emp_data.emp_name%TYPE;
emp_data.desgn%TYPE;
BEGIN
SELECT emp_name,desgn INTO
V_name,v_desgn
FROM emp_data
WHERE staffno = &&_staffno;
Select basic INTO v_basic
FROM emp-sal
WHERE staffno = &p_staffno;
35/117
Oracle
pl/sql programming
varchar2(3);
BEGIN
Tempvar := ABCD;
EXCEPTION
WHEN VALUE _ERROR THEN
INSERT INTO message
VALUES (VALUE_ERROR,
There is an error in the assignment of value to the variable);
36/117
Oracle
pl/sql programming
END;
/
Example 2:
DECLARE
Tempvar
varchar2(3);
BEGIN
SELECT staffno
INTO tempvar
FROM emp_data
WHERE staffno = 1001 ;
EXCEPTION
WHEN VALUE_ERROR THEN
INSERT INTO message
VALUES (VALUE_ERROR,
There is an error in the assignment of value to the variable);
END;
/
EXPLANATION: The error can occur either as a result of an assignment
statement or selectinto statement.
EXAMPLE FOR ZERO_DIVIDE:
DECLARE
V_maxbasic NUMBER(6);
V_MINBASIC
NUMBER(6);
V_ratio
NUMBER(5,2)
BEGIN
SELECT MAX(basic), MIN(basic)
Into v_maxbasic, v_minbasic
FROM emp_sal;
V_ratio := v_maxbasic / v_minbasic;
INSERT INTO message
37/117
Oracle
pl/sql programming
VALUES (NULL ,
The ratio between maximum and minimum basicpay is ||
to_char(v_ratio));
EXCEPTION
WHEN ZERO_DIVIDE THEN
INSERT INTO message
VALUES (ZERO_DIVIDE ERROR,
There is zero value in the basicpay);
END;
/
Now execute the program and see the result as follows
SQL>SELECT * FROM message;
OUTPUT
The ratio between maximum and minimum basic pay is x.xx (some value).
Next modify one of the basic as 0 as follows:
SQL> UPDATE emp_sal
SET basic = 0
WHERE staffno = 1001;
Again run the program and observe the result.
OUTPUT:
ZERO_DIVIDE ERROR: There is zero value in the basic pay, so when an
attempt made to divide a number by zero, the ZERO_DIVIDE exception is raised
automatically and since there was a handler in the exception section, the control
branched there and recorded the error by inserting one row in the message table.
THE EXCEPTION_INIT PRAGMA:
The standard system exceptions, such as ZERO_DIVIDE which are
referenced by name, are no more than the association of a name with the
internal ORACLE error number. There are 100s of these error numbers, and
only the most common dozen have been given names. Any that are not named
will still raise exception flag and transfer control to the EXCEPTION block, but
they will all be caught by OTHERS rather than by name.
38/117
Oracle
pl/sql programming
You can change this by assigning your own names to other ORACLE error
number. This provides named exceptions in addition to the predefined ones.
EXCEPTION_INIT allow you to do this. Exception is the one word name you
assign to the integer error number. Integer should be negative if the error code
is negative (TRUE for fatal errors) and exception must follow normal object
naming rules.
Note that the syntax of this command requires the word PRAGMA
before EXCEPTION_INIT.
A PRAGMA is not an executable code. It is a compiler directive-an
instruction to the compiler, which can be thought of as a parenthetical remark to
the compiler. PRAGMAS (also called pesudoinstructions are processed at
compile time and not at run time. The predefined PRAGMA EXCEPTION_INIT
tells the PL/SQL compiler to associate an exception name with an ORACLE
error number. That allows you to refer to any internal exception by name and to
write a specific handler for it.
SYNTAX;
1.
Declare the name for the exception within the declarative section as
follows:
Exception_name EXCEPTION;
Where exception_name is the name of the exception.
2.
Associate the declared exception with standard ORACLE error number
using PRAGMA EXCEPTION_UNIT Statement in the declarative part of PL/SQL
block, sub-program or package.
PRAGMA EXCEPTION_INIT (exception_name,error-number):
Where exception_name is the name of the previously declared exception.
The PRAGMA must appear somewhere after the exception declaration in the
same declarativepart.
3.
Refer declared exception within the corresponding exception handling
routine.
Example:
The ORACLE error that is UNIQUE or NOT NULL CONSTRAINT
violated can be associated with an exception name empty_name as follows:
DECLARE
39/117
Oracle
pl/sql programming
/* ORACLE NON PREDEFINED EXCEPTION */
empty_name EXCEPTION;
PRAGMA EXCEPTION_INIT (empty_name, -1400);
BEGIN
INSERT INTO emp_data (staffno, emp_name, deptno) VALUES
(&p_staffno, &p_name, &p_deptno);
INSERT INTO emp_sal (staffno)
VALUES (&p_staffno);
EXCEPTION
WHEN empty_name THEN
INSERT INTO message
Values (Blank Name,
Employees name cannot be blank);
END;
/
SELECT * FROM Message;
Similarly, The referential integrity constraint violated which is having code
-2292 & The table or view does not exist, having code 942 can be associated
with an exception name using PRAGMA EXCEPTION_INIT.
CUSTOMISING ERROR CONDITIONS:
You may establish different error conditions within procedural objects. For
each of the error conditions you define, you may select an error message that will
appear when the error occurs by using built in fuction
RAISE_APPLICATION_ERROR to create your own message, which can be
more descriptive than named exceptions. This procedure is defined in the
STANDARD package and may be called from within any procedural object.
The syntax of the RAISE_APPLICATION_ERROR I:
RAISE_APPLICATION_ERROR (error_number, error_message,
[Keep_errors] ;
It takes three I/P parameters: the error number (which must be between
-20001 and 20999) and the error message which is the text to be displayed and
keep_errors : a Boolean value which is optional. If keep_errors is true, the new
error is added to the list of already raised (if one exists). If it is false , which is the
40/117
Oracle
pl/sql programming
default, the new error will replace the current list of errors. You get to assign both
the message number and the text that will be displayed to the user
EXAMPLE:
PROCEDURE paycalc(p_staffno IN emp_data.staffno%TYPE)
IS
Zero_pay EXCEPTION;
BEGIN
EXCEPTION
WHEN TOO_ MANY_ ROWS THEN
RAISE_APPLICATION_ERROR (-20001,
There are more than I records for this staff number : || p_staffno);
WHEN zero_pay THEN
RAISE_APPLICATION_ERROR(-20002,
Basic pay zero seems incorrect, It needs updation);
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-2003,
There is no record of information for this staff no: || p_staffno);
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-2004,
Some other error has occurred);
END paycalc;
In the above program RAISE_APPLICATION_ERROR procedure is called
from each exception handling section to give customized error messages by
setting the error numbers and messages via this procedure. Thus the use of the
RAISE_APPLICATION_ERROR procedure give you great flexibility in managing
the error conditions that may be encountered within your trigger / procedure.
This is a very powerful addition to the standard exceptions that are available in
PL/SQL .
EXCEPTION PROPOGATION:
Exception can occur in the declarative,executable or the exception
section of a PL/SQL block. We have seen what happens when exceptions are
raised in the executable portion of the block, when there is a handler for the
exception. But what, if there is no handler, or the exception is raised from
41/117
Oracle
pl/sql programming
different section of the block? The process that governs this is known as
exception propogation.
1.
If the current block has a handler for the exception, execute it and complete
the block successfully. Control then passes to the enclosing block.
If there is no handler for the current exception, propogate the exception by
raising it in the enclosing block. Step I will then be executed for the enclosing
block.
Before we can examine this algorithm in detail, we need to define an
enclosing block. A block can be embedded inside another block. In this case,
the outer block encloses the inner block.
EXAMPLE:
DECLARE
--Begin outer block
BEGIN
--Begin inner block. This is embedded in the outer block.
BEGIN
END;
.
BEGIN
--Begin inner block 2. This is also embedded in the
-- outer block.
--Note that this block does not
-- have a declarative part
END;
.
..
--End out block
END;
42/117
Oracle
pl/sql programming
In the preceding listing, inner blocks 1 and 2 are both enclosed by the
outer block. Any unhandled exceptions in block 1 and block 2 will be
propogated to the outer block.
A procedure call will also create an enclosing block, and is
illustrated in the following example:
BEGIN
--Begin outer block.
--call a procedure. The procedure will be enclosed by the
--outer block.
F()
END;
If procedure function raises an unhandled exception, it will be
propogated to the outer block, since it encloses the procedure.
TRIGGERS
INTRODUCTION
Like procedures, functions and packages. Triggers are named PL/SQL blocks
with declarative, executable and exception handling sections. Like packages,
Triggers must be stored in the database and cannot be local to a block .
However a procedure is executed explicitly from another block which can pass
arguments. But a trigger is executed implicitly, whenever the triggering event
happens and a trigger does not accept arguments. The act of executing a
trigger is known as firing the trigger. The triggering event is a DML (INSERT,
UPDATE, DELETE) operation on a database table.
APPLICATION OF TRIGGERS
Triggers can be used for many things, including
43/117
Oracle
pl/sql programming
CREATING TRIGGERS
SYNTAX
The general syntax for creating a trigger is:
CREATE [OR REPLACE] TRIGGER trigger _name
[BEFORE | AFTER ] triggering event ON table_reference [For EACH
ROW ]
[ WHEN trigger_condition ]
trigger_body;
where
trigger_name -the name of the trigger
triggering-event The event or time when the trigger fires.
Table_reference The table for which the trigger is defined
Trigger_body
Main code for the trigger
Trigger_condition The body of the trigger is executed only when the
condition evaluates to TRUE.
EXAMPLE
As an example, suppose we want to track statistics about different
category of subscribers, exchange wise. We want to
store these results in exg_stats table. The following script will create the
table exg_stats.
CREATE TABLE exg_stats
(exg_code CHAR (5),
cat_code NUMBER(2);
no_of_subs NUMBER (5));
In order to keep the table exg_stats up-to-date, We can create a trigger
on the table master_data that will update table exg_stats every time the
table master _data is modified. The update_ES TRIGGER shown next
does this. After any DML operation on the tableMaster_data the trigger
update_ES will execute. The body of the trigger queries the table
master_data and updates the table exg_stats with the current statistics.
CREATE OR REPLACE TRIGGER update_ES
/* Keeps the major_stats table up-to-date with the changes made to the
table master_data*/
AFTER INSERT OR DELETE OR UPDATE ON master_data
44/117
Oracle
pl/sql programming
DECLARE
CURSOR c_stats IS
SELECT exg_code,cat_code, count (*), no_of_subs
FROM master_data
GROUP BY exg_code,cat_code;
BEGIN
/*Loop through each record of the table exg_stats. Attempt to update the
statistics. If the row does not exit, create it */
FOR v_statsRecord IN C_stats LOOP
UPDATE exg_stats
SET no_of_subs = v_statsRecord.no_subs
WHERE exg_code = v_statsRecord.exg_code
AND Cat_code = v_statsRecord.cat_code;
/*Check to see if the row exists*/
IF SQL%NOTFOUND THEN
INSERT INTO exg_stats (exg_code,cat_code,no_of_subs)
VALUES (v_statsRecord.exg_code,v_stats
Record.cat_code,v_statsRecord.no_subs);
END IF;
END LOOP;
END update_ES;
TRIGGER COMPONENTS
1.Trigger name
2.Triggering event
3.The body
4.When clause -optional.
Trigger Name
Namespace: A namespace is the set of legal identifiers available for use as the
names of an object. Within one database shema ,all objects in the same
namespace must have unique name. Procedures, Packages and Tables all share
the same namespace. Hence it is illegal to give the same name to a procedure
and a table.
The namespace for triggers is different from that of the above objects (i.e.,
procedure, package and table). This means that a trigger can have same name
as a table or a procedure.
45/117
Oracle
pl/sql programming
Trigger names are database identifiers and as such follows the same rules as
other identifiers.
Although it is possible to use the same name for a trigger and a table. It is
better to give each trigger a unique name that identifies its function as well as the
table at which it is defined.
Triggering event
The triggering event determines the type of the triggers.
Triggers can be defined for INSERT, UPDATE or DELETE operation.
Triggers can be fired BEFORE or AFTER the operation.
They can also be fired ROW or STATEMENT level
TABLE I
Category
Statement
Timing
Level
Values
INSERT
DELETE
UPDATE
BEFORE
AFTER
ROW
Comments
Defines which kind of DML statement
causes the trigger to fire.
Defines whether the trigger fires before or
after the statement is executed.
Fires once for each row affected by the
triggering Statement.
Fires only once either before or after the
statement.
STATEMENT
TABLE 2
Timing
Statement
Level
BEFORE
INSERT
UPDATE
DELETE
ROW
AFTER
STATEMENT
The values for the timing, statement and level determine the type of the trigger.
From the table 2 it can be observed that there are total of possible 12 types.
2 timings x 3 statement x 2 levels = 12 types
For example all the following are valid trigger types.
46/117
Oracle
pl/sql programming
47/117
Oracle
pl/sql programming
48/117
END
Oracle
pl/sql programming
INSERT INTO otf_table (ord_no,tgr_type)
VALUES (tgr_seq.NEXTVAL, After Row Trigger);
END staff_Arow;
/* To test the otf_trigger*/
UPDATE staff
SET Salary = 10000
WHERE desgn = AO;
:Old
:new
Undefined-All fields
Are NULL
UPDATE
DELETE
TABLE-3
The Table-3 shows the value of :new and :old with reference to each
statement. In reality, :new and :old are not records. As a result, operations that
would normally be valid on records are not valid for :new and :old . For example,
49/117
Oracle
pl/sql programming
i.
They cannot be assigned as entire record. Only the individual fields within
them may be assigned.
ii.
:old and :new cannot be passed to procedures or functions that take
arguments of triggering_table%ROW TYPE.
The Generate_EmpId trigger shown next uses :new. It is a BEFORE INSERT
OR UPDATE Trigger and its purpose is to fill in the ID field of staff with a value
generated from the emd_id__seq sequence.
Example:
The trigger Generate_EmpId actually modifies the value of
:new.emp_id. When the statement is actually executed, whatever values in :new
will be used. With Generate_EmpId, we can issue an INSERTstatement such as:
INSERT INTO STAFF (emp_name, desgn)
VALUES JOSE, AO);
Without generating an error. Even though we have not specified a value for
the primary key column emp_id (which is required), the trigger will supply it.
Infact, even if we do specify a value for emp_id, it will be ignored, since the
trigger changes it.
If we issue
INSERT INTO staff (emp_id,emp_name,desgn)
VALUES (51,JOSE, AO);
We get the same behaviour. In either case, emp_id_seq.NEXTVAL will be used
for emp_id column.
This shows that, you cannot change :new in an AFTER ROW LEVEL trigger,
since the statement had already been processed.
Note:
In general, :new is modified only in a before row level trigger and :Old is
never modified, only read from.
The :new and :old records are only valid inside a ROW LEVEL triggers.
You will get a compile error, if you try to reference inside a STATEMENT
LEVEL trigger.
Oracle
pl/sql programming
- The WHEN clause is valid for row level triggers only. If present, the trigger
body will be executed only for those rows that meet the condition specified by the
WHEN clause. The WHEN clause looks like:
WHEN condition
- Where condition is a Boolean expression. It will be evaluated for each row.
The :new and :old records can be referenced inside conditions as well, but the
colon is not used there. The colon is only valid in the trigger body. For example,
the body of the check_salary trigger is only executed if the salary of an employee
is more than 10000.
CREATE OR REPLACE TRIGGER Check _salary
BEFORE INSERT OR UPDATE OF salary ON employee
FOR EACH ROW
WHEN ( :new.salary > 10000)
BEGIN
/* Trigger body goes here. */
END;
Check _Salary could also be written as follows:
CREATE OR REPLACE TRIGGER check_salary
BEFORE INSERT OR UPDATE OF salary ON students
FOR EACH ROW
BEGIN
IF :new.salary > 10000 THEN
/* Trigger body goes here */
END IF;
END;
USING TRIGGER PREDICATES:
INSERTING, UPDATING AND DELETING
The update_trigger earlier in this chapter is an INSERT, UPDATE and a
DELETE TRIGGE. Inside a trigger of this type (that will fire for different kinds of
DML statements), there are three Boolean functions that you can use to
determine what the operation is. These predicates are INSERTING, UPDATING
and DELETING. Their behaviour is described in the following table.
Predicate
INSERTING
Behavior
TRUE, if the triggering statement is an
INSERT;FALSE otherwise.
51/117
Oracle
UPDATING
DELETING
pl/sql programming
TRUE if the triggering statement is an
UPDATE;FALSE otherwise.
TRUE if the triggering statement is a
DELETE;FALSE otherwise.
Oracle
pl/sql programming
V_change_type := D;
END IF;
/* Record all the changes made to staff table in staff_audit table. Use SYSDATE
to generate the timestamp, and USER to return the user_ id of the current user. */
53/117
Oracle
pl/sql programming
Cursor
What is a Cursor ?
A cursor is a private SQL area
Every SQL statement executed by the oracle server has
an individual cursor associated with it.
Two Types of cursor:
-Implicit cursors: Declared for all DML and
PL/SQL SELECT statements.
-Explicit cursors: Declared and named by the
programmer.
The Oracle Serve uses work areas called Private SQL
areas to execute SQL statements and store processing
information. PL/SQL cursors let you name a private SQL area and
access its stored information. The cursor directs all phases of
processing.
Cursor Description
Type
Implicit Declared by PL/SQL implicitly for all DML
and PL/SQL SELECT statements.
Explicit Declared and named by the programmer
and manipulated through specific
statements within the blocks executable
actions.
Recall that the SELECT statement in PL/SQL must only return a
single row. PL/SQL actually attempts to fetch two rows from an
implicit cursor: one to satisfy the query and a second to see if
further rows were returned. One method to eliminate this extra fetch
is to use an explicit cursor.
Can process beyond the first row returned by the query, row by row.
Keep track of which row is currently being processed.
Allow the programmer to manually control them in the PL/SQL block.
54/117
Oracle
pl/sql programming
1.
2.
3.
4.
5.
FETC
H
OPEN
(2)
empty
(3)
(4)
CLOSE
yes
(5)
55/117
Oracle
pl/sql programming
Syntax:
DECLARE
CURSOR cursor_name IS
Select_statement;
Where:
Cursor_name
is a PL/SQL identifier.
Select_statement
Note: Do not include the INTO clause within the cursor declaration because it
appears later within the FETCH statement.
56/117
cursor.
Oracle
pl/sql programming
Note: If the query returns no rows when the cursor is opened, PL/SQL does not
raise an exception. However, you can test the cursor_ status after a fetch.
Opening the Cursor : Syntax
Open the cursor to execute the query and identify the active set.
OPEN cursor_name;
If the query returns no rows, no exception is raised.
Test the outcome after a fetch by using cursor attributes.
Where:
cursor-name
Variable
Guidelines:
Include the same number of variables within the INTO clause of the
FETCH statement as output columns in the SELECT statement and be
sure that the data types are compatible.
Match each variable to correspond to the columns positionally.
Alternatively, define a record for the cursor and reference the record in the
FETCH INTO clause.
Test to see if the cursor contain rows. If a fetch acquires no values, that is
there are now rows left to process in the active set and no error is
recorded.
57/117
Oracle
pl/sql programming
Fetching Data from the Cursor: Syntax:
Retrieving the current row values into output variables.
FETCH cursor_name INTO variable1,
variable2;
Include the same number of variables.
Match each variable to correspond to the columns
positionally.
Test to see if the cursor contains rows.
cursor.
Note: Do not attempt to fetch data from a cursor once it has been closed
or the INVALID_CURSOR exception will be raised.
58/117
Oracle
pl/sql programming
Closing the Cursor: Syntax
Description
%ISOPEN
%Notfound
%FOUND
%ROWCOUNT
59/117
Oracle
pl/sql programming
You can only fetch rows when the cursor is open. Determine
whether the cursor is open using the %ISOPEN cursor attribute, if
necessary.
Fetch rows in a loop. Determine when to exit the loop by using
cursor attributes.
To retrieve an exact number of rows, fetch the rows in a numeric
FOR loop, or fetch the rows in a simple loop and determine when
to exist the loop by using the %ROWCOUNT cursor attribute.
Example:
Retrieve the first five line items for an order one by one. Print the
cumulative total for each product to the screen.
PROCEDURE ord_process
V_ord_id IN s_item.ord_id%TYPE;
IS
V_product_id s_item.product_id%TYPE;
V_item_total NUMBER (11,2);
V_order_total NUMBER (11,2) :=0;
CURSOR item_cursor IS
SELECT product_id, price * quantity
FROM
s_item
60/117
Oracle
pl/sql programming
WHERE ord_id = v_ord_id;
BEGIN
OPEN item_cursor;
LOOP
FETCH item_cursor INTO v_product_id ,
V_item_total;
EXIT WHEN item_cursor%ROWCOUNT > 5
OR item_cursor%NOTFOUND;
V_order_total := v_order_total + v_item_total;
TEXT_IO.PUT_LINE ( Product ID ||
TO_CHAR (v_product_id) ||
has a total of ||
TO CHAR(v_order_total , $999,999,999.99));
END LOOP;
CLOSE item_cursor;
COMMIT;
END ord_process;
Note: If using %ROWCOUNT, add a test for no rows in the cursor by using
the %NOTFOUND attribute because the row count is not incremented if
the fetch does not retrieve any rows.
The %ISOPEN Attribute: Example
Fetch rows only when the cursor is open.
Test if the cursor is open using %ISOPEN cursor attribute before
performing a fetch.
IF item_cursor %ISOPEN THEN
FETCH item-cursor INTO v_quantity, v_price,
ELSE
OPEN item-cursor;
END IF;
61/117
Oracle
pl/sql programming
The %NOTFOUND and
%ROWCOUNT Attributes; Example
Retrieve an exact number of rows using the %ROWCOUNT cursor attribute.
Determine when to exist the loop using the %NOTFOUND cursor attribute.
LOOP
FETCH item_cursor
INTO v_product_id, v_item_total;
EXIT WHEN item_cursor%ROWCOUNT > 5
OR item_cursor%NOTFOUND;
V_order_total := v_order_total + v_item_total;
.
END LOOP;
62/117
Oracle
pl/sql programming
Do not declare the record that controls the loop. Its scope is only in the
loop.
Test the cursor attributes during the loop, if required.
63/117
Oracle
pl/sql programming
Supply the parameters for a cursor, if required, in parentheses following
the cursor name in the FOR statement.
Do not use a cursor FOR loop when the cursor operations have to be
handled manually.
64/117
Oracle
pl/sql programming
Summary
Cursor Types
Implicit cursors are used for all DML statements and single row queries.
Explicit cursors are used for queries of zero, one, or more rows.
Cursor Attributes
Evaluates the status of the cursor by using cursor attributes.
Cursors with Parameters
Use parameter to open an explicit cursor several times in a block, returning a
different active set on each occasion.
Cursor FOR Loops
65/117
Oracle
pl/sql programming
Use cursor FOR loops as a shortcut to open the cursor, fetch rows once for each
loops iteration, and automatically close the cursor after all rows are processed.
CHAPTER 3
STORED PROCEDURES, FUNCTIONS & PACKAGES
SUBPROGRAM
Program units are named PL/SQL blocks. They fall into three main
categories.
Concept
Location
Executed
Stored Subprogram
Is in the database
From any database tool
or application
66/117
Application Subprogram
Is within the application.
From only the application
in which it was created.
Oracle
pl/sql programming
Availability
By way of database
security.
67/117
Oracle
pl/sql programming
Subprogram Components
HEADER -Mandatory
- -subprogram name,type,and
arguments
DECLARATIVE -Optional
- -Local identifiers
EXECUTABLE -Mandatory
- -SQL Statements
- -PL/SQL control statements
EXCEPTION HANDLING-Optional
- -Actions to perform when errors
occur
END; - Mandatory
Creating a Subprogram
Select environment
Invoke
68/117
Oracle
pl/sql programming
Guidelines
STORED PROCEDURES
Create a PL/SQL procedure to store a series of actions for later
execution. The procedure can contain zero or more parameters, which
are arguments that you list when calling the procedure.
69/117
Oracle
pl/sql programming
Where:
Name
Parameter
PL/SQL_BLOCK
performed
Syntax
Parameter_name [ IN | OUT | IN OUT ] datatype
[ { := | DEFAULT } expr ]
Where:
Parameter_name - is the name of the parameter.
Datatype
- is the data type of the parameter, without constraints.
Expr
- is the value to initialize the parameter.
Guidelines
70/117
Oracle
pl/sql programming
Procedural Parameters
Transfer values to and from the calling environment through parameters.
There are two types that you use. When declaring a procedure, the formal
parameter is used to define the values used in the executable portion of the
PL/SQL block. The actual parameter, or argument, is referenced when
invoking a subprogram.
OUT
Description
Default argument.
Passes a value from the calling environment into the
subprogram.
Formal parameter acts as a constant -you cannot overwrite the
value.
Actual parameter can be an expression, a constant, a literal, or
an initialized variable.
Must be specified.
Returns a value from the procedure to the calling environment.
Formal parameter acts as an uninitialized variable.
Formal parameter cannot be assigned to another variable or to
itself.
71/117
Oracle
IN OUT
pl/sql programming
Actual parameter must be a variable ; it cannot be a constant
or expression.
Must be specified.
Passes a value from the calling environment into the
procedure, and returns a possibly different value from the
procedure to the calling environment.
Formal parameter acts as an initialized variable.
Formal parameter can be used as a normal variable, it can be
assigned to a value.
Actual parameter must be a variable.
72/117
Oracle
pl/sql programming
OUT
Must be specified
Returned to calling
environment
An initialized variable.
IN OUT
Must be specified.
Passed into subprogram:
Returned to calling
environment.
An initialized variable.
Must be a variable.
Must be a variable.
Example:
Update the salary of the specified employee to the specified amount through a
procedure.
PROCEDURE change_salary
(v_emp_id IN NUMBER,
v_new_salary IN NUMBER)
- - formal parameters
IS
BEGIN - begin PL/SQL block
UPDATE s_emp
SET
salary = v_new_salary
WHERE id = v_emp_id;
COMMIT;
END change_salary;
This procedure, when invoked, will take the parameters for the employee
number and the new salary, and update the salary for that specified employee.
Eliminate Unnecessary IN Arguments
73/117
Oracle
pl/sql programming
Where possible, derive values in the procedure, or use column default
values.
Generate the primary key using a database sequence.
Record the username from the USER function.
Record the current date from the SYDATE FUNCTION.
Take advantage of business rules to compute input values automatically
using a formula.
FUNCTION
Parameter
Data type
Pl/sql_block
74/117
Oracle
pl/sql programming
Creating a Function
Example:
Return the tax based on the value parameter in a function
FUNCTION tax
(v_value IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURN (v_value * .07);
END tax;
Avoid using the OUT and IN OUT modes with FUNCTIONS.
Functions are designed to return a single value.
75/117
Oracle
pl/sql programming
PACKAGES
INTRODUCTION
Packages are PL/SQL objects that group other object such as
procedures, functions, types, variables, SQL Cursors and Exceptions as a single
unit with less restriction with respect to dependencies. This is another ADA
feature incorporated in PL/SQL . Packages also provide global variables for
PL/SQL. So packages allow multiple procedures to use the same Variables and
cursors. Procedures within packages may be available to the public in which
case they are accessible to the users of the package or they may be private, in
which case they are only accessible via commands from within the package such
as call from other procedures.
Each package has two parts: The specification and the body. Each of
them stored separately in the data dictionary. The package specification is also
known as the package header. It contains information about the objects you can
access when you use the package. However it does not contain the code for any
procedure.
CREATING PACKAGE
When creating package, the package Specification and the package body
are created separately. Thus there are two commands to use (1) CREATE
PACKAGE for package Specification, and (2)CREATE PACKAGE BODY for the
package body. Both of these commands require that you have the CREATE
PROCEDURE System Privilege. If the package is to be created in a schema
other than your own, then you must have the CREATE ANY PROCEDURE
System privilege.
The Syntax for creating package specification is:
CREATE [ or REPLACE ] package [user.] package_name
{ IS/AS }
procedure_specification |
function_specification |
variable_declaration |
exception_declaration |
cursor_declaration
type_definition
END [package_name];
Where package-name is the name of the package
76/117
Oracle
pl/sql programming
Example:
CREATE PACKAGE salary_package
As
PROCEDURE addemp (p_staffno IN emp_data.staffno%TYPE,
P_emp_name IN emp_data. Emp_name%TYPE,
P_desgn IN emp_data.desgn%TYPE, p_dob IN
Emp_data.dob%TYPE, p_hq IN emp_data.Hq%TYPE,
p_deptno IN Emp_data.deptno%TYPE);
PROCEDURE salupd (p_staffno IN emp_sal.staffno%TYPE,
P_basic IN Emp_sal.basic%TYPE,p_gpf_sub IN
emp_sal.gpf_sub%TYPE,p_gpf_rec
IN emp_sal.gpf_rec%TYPE,p_qtrs IN
emp_sal.qtrs%TYPE);
PROCEDURE Paybillgen;
PROCEDURE Paycalc (p_staffno IN emp_data.staffno%TYPE);
FUNCTION DA (p_basic IN emp_sal.basic%type)
RETURN number;
FUNCTION hra (p_basic IN emp_sal.basic%TYPE,
p_qtrs IN emp_sal.qtrs%TYPE)
77/117
Oracle
pl/sql programming
RETURN number;
END salar_package;
THE PACKAGE BODY
The package body fully defines the code for all the objects listed in the
specification and can contain additional objects not listed in package
specification. The second one objects is said to be private and are not available
to the users of the package. Private objects may only be called by other objects
within the same package body. The syntax for creating package body is:
CREATE [or REPLACE] PACKAGE BODY [User.]package_body
[IS/ AS]
PL/SQL package body;
Where package-body is the name of the package body which should be
the same as the name of the package specification. Continuing the
SALARY_PACKAGE example, its package body can be created via the
CREATE PACKAGE BODY command as follows;
Example:
CREATE PACKAGE BODY salary_package
AS
Crtdate DATE;
Crtmonth varchar2(9);
PROCEDURE addemp (p_staffno IN
emp_data.staffno%TYPE, p_emp_name IN
emp_data.emp_name%TYPE, p_desgn IN
emp_data.desgn%TYPE,
p_dob IN emp_data.dob%TYPE, p_hq IN
emp_data.hq%TYPE,
p_deptno IN emp_data.deptno%TYPE)
IS
V_deptno emp_data.deptno%TYPE;
Empty_staffno EXCEPTION;
BEGIN
IF p_staffno IS NULL
RAISE empty_staffno;
ELSE
SELECT deptno into v_deptno
78/117
Oracle
pl/sql programming
FROM dept
WHERE deptno = p_deptno;
INSERT INTO emp_data
VALUES(p_staffno, p_emp_name, p_desgn, p_dob,
p_hq, p_deptno);
INSERT INTO new_emp
VALUES (p_staffno,p_emp_name,crtdate,crtmonth);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND then
RAISE_APPLICATION_ERROR( -20001,
Department No: || p_deptno || does not exist );
WHEN DUP_VAL_ON_INDEX then
RAISE_APPLICATION_ERROR( -20002,
Staff Number : || p_staffno || should not be empty );
END addemp;
PROCEDURE salupd (p_staffno IN emp_sal.staffno%TYPE,
P_basic IN emp_sal.basic%TYPE,
P_gpf_sub IN emp_sal.gpf_sub%TYPE,
P_gpf_rec IN emp_sal.gpf_rec%TYPE,
P_qtrs emp_sal.qtrs%TYPE)
IS
Begin
Update emp_sal
SET basic = p_basic,
Gpf-sub
= p_gpf_sub,
Gpf-rec
= p_gpf_rec,
Qtrs
= p_qtrs
WHERE staffno = p_staffno;
COMMIT;
END salupd;
PROCEDURE paycalc (p_staffno IN emp_data.staffno%TYPE)
IS
Zero_pay EXCEPTION;
V_da number (6);
v-hra NUMBER (6);
v_cca number (6);
v_totpay
NUMBER (6);
v_netpay
number (6);
v_basic
emp_sal.basic%TYPE;
v_gpf_sub emp_sal.gpf_sub%TYPE;
v_gpf_rec emp_sal.gpf_rec%TYPE;
79/117
Oracle
pl/sql programming
v_qtrs
v_name
v_desgn
emp_sal.qtrs%TYPE;
emp_data.emp_name%TYPE;
emp_data.desgn%TYPE;
BEGIN
IF v_basic = 0 THEN
RAISE zero_pay;
END IF;
SELECT emp_nam, e_desgn INTO v_name,v_desgn
FROM emp-data
WHERE staffno = p_staffno;
SELECT basic,gpf_sub,gpf_rec,qtrs
INTO v_basic, v_gpf_sub,v_gpf_rec,v_qtrs
FROM emp_sal
WHERE staffno = p_staffno;
SELECT cca INTO v_cca
FROM allowrate;
V_da := da(v_basic);
V_hra := hra(v_basic,v_qtrs);
V_totpay := v_basic + v_da + v_hra + v_cca;
V_netpay := v_totpay v_gpf_sub v_gpf_rec;
INSERT INTO paybill
VALUES (p_staffno,v_name,v_desgn,v_basic,
v_da,v_hra,v_cca,v_totpay,v_netpay);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
RAISE_APPLICATION_ERROR( -20001,
There are more than I records for this staffnumber: || p_staffno );
WHEN zero_pay THEN
RAISE_APPLICATION_ERROR( -20002,
Basic pay zero seems incorrect; It needs updatation);
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR( -20003,
There is no record of information for this staff no: || p_staffno);
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20004,
SOME OTHER ERROR HAS OCCURRED );
End paycalc;
PROCEDURE paybillgen
80/117
Oracle
pl/sql programming
IS
CURSOR payinfncur IS
SELECT staffno
FROM emp_data;
BEGIN
FOR pay_cur in payinfncur
LOOP
Paycalc(Pay_cur);
END LOOP;
END paybillgen;
FUNCTION da (p_basic IN emp_sal.basic%TYPE)
RETURN NUMBER
IS
V_da NUMBER (5);
V_darate NUMBER (5);
BEGIN
SELECT darate into v_darate
FROM allowrate;
V_da := p_basic*v_darate/100;
RETURN(v_da);
FUNCTION hra (p_basic IN emp_sal.basic%TYPE,
P_qtrs IN emp_sal.qtrs%TYPE)
RETURN NUMBER
IS
V_hra NUMBER(5);
V_hrarate
NUMBER (2);
BEGIN
SELECT hrarate into v_hrarate
FROM allowrate;
IF UPPER(p_qtrts) = Y THEN
V_hra := 0;
ELSE
V_hra := p_basic*v_hrarate/100;
END IF;
RETURN(v_hra);
End hra;
END salaray_package;
81/117
Oracle
pl/sql programming
procedures in the package header. The END clauses all have the names of their
associated objects appended to them. Modifying the end clauses in this manner
helps to clarify the ending points of the object code. Objects that are not having
forward declarations, such as EXCEPTIONS ,can be referenced in the package
body without being referenced.
Additional functions, procedures, exceptions, variables, cursors and
constants may be defined within the package body, but they will not be available
to the public unless they have been declared within the package Specification
(via the CREATE PACKAGE command).
The package body is optional. If the package header does not contain any
procedure or function (only variable declarations, cursors, types and so on ), then
the body does not have to be present. This technique is used for declaring
global variables, since all objects in a package header are visible outside the
package.
Any forward declaration in the package header must be fleshed out in the
package body. The specification for the procedure or function must be the same
in both. This includes the name of the subprogram, its parameters and the mode
of the parameters.
PACKAGES SCOPE AND EXECUTION
Any object declared in a package header is in scope and is visible outside
the package by qualifying the object with the package name. Therefore, to
execute a procedure within a package, you must first list the package name, then
the procedure name.
Example;
EXECUTE salary_package.paycalc(1001);
However inside the package body, the object in the header can be referenced
without the package name.
PACKAGE INITIALIZATION
A package body may also include code that is run every time the package is
invoked, regardless of the part of the package that is executed. In the following
e.g., SALARY_PACKAGE package body is modified to include a SQL statement
that records the current date and the current month , at the start of the package
execution. Two new variables crtdate & crtmonth also have been declared in the
package body in order to record these values. Since the 2 new variables are
declared within the package body, they are not available to the public. Within the
82/117
Oracle
pl/sql programming
package body, they are separated from the procedures and functions. The
package initialization code is shown as follows:
CREATE OR REPLACE PACKAGE BODY salary_package
AS
Crtdate
DATE;
Crtmonth
varchar2(9);
.
BEGIN
SELECT sysdate, to_char(sydate, Month)
INTO crtdate, crtmonth
FROM dual;
END salary_package;
Note: The code that is to be run every time the package is executed is
stored in its own PL/SQL block at the bottom of the package body. It
does not have its own end clause; it uses the package bodys end
clause.
Every time the salary-package package is executed the crt date and crt
month variables will be populated by the query shown in the previous
listing. These 2 variables can then be used by the function &
procedures within the package ie; Addemp procedure uses this
variables for populating in the new_emp table.
DROPPING PACKAGES
Packages and its body can be dropped separately as follows:
To drop a package, use the drop package command as shown in the
following listings:
DROP PACKAGE Salary_package;
To drop a package body, use the drop package command with the body
clause, as shown in the following listings:
DROP PACKAGE BODY salary_package;
PACKAGES AND DEPENDENCIES
The Dependency picture for salary-package is shown below:
SALARY_PACKAGE DEPENDENCIES
83/117
Oracle
pl/sql programming
SALARY_PACKAGE
HEADER
SALARY_PACKAGE
BODY
The BODY of
salary_package
depends on the
emp_data, emp_sal
& Dept tables
EMP_DATA, EMP_SAL,
& DEPT
The package body depends on emp_data, emp_sl & dept tables and
package header. The package header does not depend on anything. This is the
advantage of packages. We can change the package body without having to
change the header. Therefore other objects which depend on the header wont
have to be recompiled at all , since they never get invalidated. If the header is
changed, this automatically invalidates the body, since the body depends on the
header.
We can examine the behaviour as follows:
In the previous salary_package package, we can refer it with the body and
the table emp_data.
We can query the information about the above objects as follows.
SELECT object_name, object_type,status
FROM user_objects
WHERE object_name IN (salary_package, emp_data);
OUTPUT:
OBJECT_NAME
SALARY_PACKAGE
SALARY_PACKAGE
EMP_DATA
OBJECT_TYPE
PACKAGE
PACKAGE BODY
TABLE
84/117
STATUS
VALID
VALID
VALID
Oracle
pl/sql programming
OBJECT_TYPE
PACKAGE
PACKAGE BODY
TABLE
STATUS
VALID
VALID
VALID
OBJECT_TYPE
PACKAGE
PACKAGE BODY
STATUS
VALID
INVALID
85/117
Oracle
pl/sql programming
CHAPTER 4
ORACLE ARCHITECTURE AND USER MANAGEMENT
ARCHITECTURE OF THE ORACLE SERVER
INIT.ora.
This file contains entries that determine the runtime
environment of the Oracle 9i database as it operates. The values for the
entries in this file control items such as the amount of memory allocated
to the instance and the breakdown of the structures within that memory.
Shared memory
Often referred to as RAM on the PC, this is an
amount of a computers memory that is acquired when an Oracle 9 i
database is started. This chunk of memory is acquired when the Oracle 9i
server is started and is affectionately called the SGA, or system global
area.
Database files
These fall into three categories-data files, control
files, and redo log files. The files that end in .dbf are data files, the ones in
.ctrl are control files, and .log files are online redo logs.
Network access
This is enabled by Oracle 9is Oracle Net product,
Its precursors were SQL*Net, delivered with versions upto and including
Oracle7, and Net8 with all releases of Oracle8.
Trace files
These are continually written to as Oracle9i operates and
are deposited in locations specified in an instances INIT.ora. They
contain primiarily two kinds of descriptive information -certain types of
Oracle errors and timestamp information related to some significant
instance activities.
Runtime libraries
These are the equivalent of PC dynamic link libraries,
containing routines and service components that allow the Oracle9i server
to operate and perform a suite of sophisticated functionally on its user
communitys behalf.
86/117
Oracle
pl/sql programming
87/117
Oracle
pl/sql programming
88/117
Oracle
pl/sql programming
INIT.ora
The INIT.ora file is read when an Oracle9i instance is started .
Let us look at the type of parameters found in the INIT.ora file and a few
examples of each.
Location Entries
The first category of parameters describes the location of one or
more files required by or written to as the instance operates. In some cases, it
contains the fully pathed location, directory, and file name, as in control_files. In
other cases, it simply contains a directory name, as in db_create_file_dest.
When the instance is started, Oracle9i verifies that the directories and files
mentioned in INIT.ora exist and can be written to and read from. If there are any
problems, Oracle9i displays one or more error messages along the lines of those
shown in the next listing.
SQL> startup
ORA-00444: background process LGWR failed while starting
SQL>
SQL> startup
ORACLE instance started.
Total System Global Area 537691548 bytes
Fixed Size
279964 bytes
Variable Size
469762048 bytes
Database Buffers
67108864 bytes
Redo Buffers
540672 bytes
ORA-00205: error in identifying controlfile, check altert log for more info
Limiting Entries
Parameters that list a number for controlling implementation of a
feature of the Oracle9i server usually fall into one of two categories:
Resource limiters - How many resource items should be made available
to the instance upon startup. The entries open_cursors, open_links, and
timed_statistics fall into this realm.
Memory allocations - How much memory should be set aside for the
piece of functionality described by these entries. The most commonly
changed parameters in this class are db_cache_size, shared_pool_size,
and sort_area_size. Some of these entries accept k for kilobytes, m
for megabytes, and g for gigabytes; others simply accept an integer
number of bytes.
89/117
Oracle
pl/sql programming
There are some operating system -and Oracle9i -enforced minimums and
maximums that can be specified for these entries, and if they exist on your
hardware platform, you will be told when the instance is started. An occurrence
of this is shown in the next listing.
/d0/oraclehome/product/oracle9.0.1/dbs> sqlplus /nolog
SQL*Plus: Release 9.0.1.0.0. Production on Sun Jun 17 13:44:09 2009
( c ) Copyright 2001 Oracle Corporation . All rights reserved.
SQL> connect / as sysdba
Connected to an idle instance.
SQL> startup
ORA-00093: shared_pool_reserved_size must be between 5000 and 8388608
Feature Entries
Feature entries also fall into two categories:
Those that can only specify keywords like true, false, partial, or full. A
few parameters that fall into this category are max_dump_file_size,
oracle_trace_enabled, and row locking. Any values other than those in
the approved list for each parameter will be rejected, as shown next.
Oracle
pl/sql programming
shown in the next listing is where you can deduce what parameters can be
changed without bouncing (shutdown followed by startup) the database.
SQL> desc v$parameter
Name
Null?
Type
------------------------------------------------------------NUM
NAME
TYPE
VALUE
ISDEFAULT
ISSES_MODIFIABLE
ISSYS_MODIFIABLE
ISMODIFIED
ISADJUSTED
DESCRIPTION
UPDATE_COMMENT
NUMBER
VARCHAR2(64)
NUMBER
VARCHAR2(512)
VARCHAR2(9)
VARCHAR2(5)
VARCHAR2(9)
VARCHAR2(10)
VARCHAR2(5)
VARCHAR2(64)
VARCHAR2(255)
You may now have a preliminary knowledge of INIT.ora , what this file is all
aboutThe Control File
Oracle9i builds a control file when a database is created; you require only
one control file per instance, but best practices dictate at least two of these
files, at all times. This file is a road map to the Oracle9i database and
contains instance-specific information such as
91/117
Oracle
pl/sql programming
Null?
Type
VARCHAR2 (7)
VARCHAR2(513)
The startup and shutdown of the Oracle9i database uses the instance
control files for consistency and completeness checking. When we speak of
consistency, we refer to the cross-file dependencies all over the Oracle9i
database that are checked and rechecked on startup and shutdown. In this
context, completeness means a check for the presence of and accessibility to all
the files mentioned in the control files. Let us look now at the redo or transaction
logs.
Redo Logs
The redo log files are the heart of the proprietory Oracle9iserver. Some
other vendors may have a similar facility for tracking the activity against their
database. Oracle will write to any number of redo log files that the DBA chooses
to specify. Redo logs were introduced in Oracle V6 (circa 1988), and with
Oracle7 in February 1993, redo log files were enhanced to become multimembered redo log groups. When DBA now talk about the online redo logs,
they really mean online redo log groups.
When redo log groups are created, we give them an integer number,
which becomes the group number to which they are referred by the DBA. We
then speak of redo log group 1or redo log group 2, and so on. As users interact
with the Oracle9i database, a record of their activities is written to the online redo
logs at commit or rollback time. Redo logs are a finite size, and when they fill up,
Oracle switches to another set of log files.
NOTE
Each member of the same redo log group is a mirror image of the other
members in the same group.
Oracle9i needs at least two single-membered redo log groups to operate,
though we recommend at least three two-membered redo log groups. These
must be made manually using a GUI such as OEM or SQL*Plus. When a redo
log group fills up, Oracle switches to the next available group. Before a group is
marked available, Oracle marches through each redo log group reconciling any
outstanding activities, and then marks the group able to be used the next time a
switch occurs. The question you may have already asked yourself is What if a
group has not yet been marked as reusable and its turn comes up?. Oracle9i
suspends activity against the database until the group is marked reusable, and
92/117
Oracle
pl/sql programming
Group 2
Group 1
Group 3
.
Figure 1 -The circular re-use of the online redo log groups
Note
Online redo log file information can be viewed in the v$logfile data
dictionary view shown in the next listing.
SQL>desc v$logfile
Name
Nul?
Type
---------------------------------------------GROUP#
NUMBER
STATUS
VARCHAR2(7)
TYPE
VARCHAR2(7)
MEMBER
VARCHAR2(513)
Oracle
pl/sql programming
reco
pmo
n
smon
Dbw0
SHARED
MEMORY
( SGA)
LGWR
R
ckpt
Data
files
Control
files
94/117
Arc0
Offline
Offline
storage
Offline
storage
Online
storage
redolog
Offline
storage
Oracle
pl/sql programming
Oracle
pl/sql programming
Entity
Database
Tablespace
Data file
Is a superset of
Tablespace / data file
Datafile
Belongs to
Database
Tablespace
Activity
Undo
1
2
Pretransaction #1
Update savings set balance
= balance + 12000 where
account = 55524;
Rollback;
Update savings set balance
= Balance + 1200
where account = 55524;
Commit;
3
4
5
Empty
940
Data in
memory
940
12,940
Seen by
others
940
940
Empty
940
940
2,140
940
940
Empty
2,140
2140
Oracle
pl/sql programming
information for account 55524 was on disk, not having yet been read into
memory. As the transaction begins, the data is scooped into memory, the update
applied, and undo space reserved for the sake of other users. When the
rollback; is issued, the data that was supposed to have been updated is left in
memory, with its old value, and the undo released. It is the same story when the
transaction is reinitiated, and upon commit; the undo is released and the new
value, in memory, is available to SID 99 and all other sessions. The secret of this
read consistent model is illustrated in another way in Table 3 showing how the
concurrent user community sees the data in account 55524.
-------------------------------------------------------------------------------------------------Balance Value Seen and from Where
( D = database, M = Memory, U = undo)
State
SID 99
Other Sessions
1
940 (D)
940 (D)
2
12,940 (M)
940 (U)
3
940 (M)
940 (M)
4
2,140 ( M)
940 (U)
5
2.140 (M)
2,140 (M)
--------------------------------------------------------------------------------------------------TABLE - 3 Who Views What Value and from Where
The m word (memory) keeps surfacing in this section. Speaking of memory, let
us move on and look at two significant areas in shared memory -the library
cache and the data cache. The next section will just about round out the
discussion of Oracle9i architecture.
Significant Memory Structures
Oracle9i is a fabulous user of computer memory. Here, we are going to
have a look at the two most significant memory structures-the library cache and
the data cache.
The Data Cache
Oracle9i sets aside a portion of its SGA to hold data read from the
database files and / or getting ready to be written back to those same files. The
size of the data cache is determined by a handful of INIT.ora parameters, the
most common being db_cache_size. This entry specifies a default cache size in
megabytes (using m) or an absolute number of bytes.
97/117
Oracle
pl/sql programming
Figure 3 highlights how Oracle 9i uses its data cache. User sessions
read and manipulate data in this cache. They do not directly interact with the
database files. All data, regardless of what ends up happening to it, passes
through memory on its way to these user sessions.
Oracle9i deliberately uses memory to store data as it is massaged by the
user community. Printing, reading from disk drives, and memory access are
common activities performed as systems operate, listed from slowest to fastest.
One can justifiably claim that the speed with which the printer churns out the
printed word ,sets the standard for the speed of the computer. The point of all
this ? If you had a choice between reading Oracle9i data directly from disk or
memory, which would you choose- access at the speed of the printer or from
memory? Here is a hint- when read from memory, the access is virtually at the
speed of light, or 280,000 kilometers per second.
Oracle9i moves data into memory before making it accessible to user
sessions. These sessions work with the data in memory, the data gets marked
as changed, where appropriate, and eventually gets written back to disk.
Oracle9i performs all its data manipulation in the data cache, a finite amount of
computer memory.
USER SESSIONS
User sessions read data from
and return data to the data cache
Data cache
SGA
Library
cache
98/117
Oracle
pl/sql programming
Cache sizes of 400MB to 500MB are common on some of the higher-end UNIX
Servers. Oracle9i manages the space in the data cache using a least recently
used, or LRU, algorithm. Data gets aged out of the cache when the space it
occupies is required for other data. The LRU rule ensures that data used the
longest time ago is flushed before the more active data. Once an Oracle9i
instance is started, you need not perform any manual maintenance of the data
cache
The Library Cache
The library cache is where all the SQL and PL/SQL statements reside in
memory. All theOracle9i database engine understands is SQL; regardless of
what you use to facilitate user interaction with the database. SQL is what gets
sent off to the software for processing. This cache is sized primarily by
shared_pool_size in INIT.ora, with absolute values in bytes or the megabyte
measurement followed by the m abbreviation. In a nutshell, the following steps
are how Oracle9i processes SQL:
Statement is passed to Oracle9i for processing.
.Before it is placed in the library cache, a hash value is computed that
represents a number of characteristics of the SQL.
Oracle compares the computed hash value against those values in a
hash table it maintains for SQL statements already in the cache.
If a match is found, the new SQL statement is thrown away and the one
sitting in the cache is executed on its behalf.
If no match is found, further processing is done on the new SQL
statement, and entry is made in the library cache hash table for the
newly arrived code, and it is placed in the library cache.
Any SQL statement executed against the Oracle9i database must first be
placed in the library cache and marked ready-to-execute. This library cache, is
also referred to as the shared pool.
99/117
Oracle
pl/sql programming
without these protection mechanisms, the smooth and consistent operation of the
database would be in question.
Locks
Oracle9i uses locks to ensure that different sessions are not able to
interact with the same data in use by other sessions. Interact in this context
means anything other than select. This protects the integrity of the data and is
managed automatically by Oracle9i, without need for manual intervention. Locks
are acquired as SQL statements begin their interaction with data and last for the
duration of a transaction. Transactions commonly end with a commit or
rollback, the latter restoring data to its pre-transaction state. Oracle9i uses two
locking modes:
Exclusive mode will not allow the locked resource to be shared what-soever by any concurrent sessions. This lock is acquired to modify data or
define the structures within which data resides.
Share mode allows concurrent read access to the same chunk of data,
with escalation to an exclusive mode lock when change is initiated.
Oracle 9i obtains a share mode lock on a row of data as it is accessed as
part of the result set to a query. If, and only if, that query leads to an update or
delete statement, the lock is escalated to an exclusive row lock, if the row is not
already locked in that mode. Oracle9i allows simultaneous updates to rows
sitting in the same data block. If two sessions request update access to the
same row in the same data block, they queue up and go about their business in
a serial fashion. There are two types of locks Oracle9i acquires on its data;
DML locks, or data manipulation locks, ensure data integrity in multi- user
environments for the purposes of protecting data.
DDL locks, or data definition locks, protect the structure of objects and are
acquired for data definition activities.
Oracle
pl/sql programming
DBA need not worry themselves about latches unless they cause
problems in their databases, if they ever do. Suffice it to say, latches are part
of the puzzle fundamental to the operation of the Oracle9i database and,
most of the time, go about their work unnoticed. They are an essential player
in the running of the instance . We find it almost ironic that the words lock and
latch both start with the same letter-/-and the words look out start with the
same letter, which is what you will do if your locks and latches lead to
significant wait situations. The hourglass displayed by the mouse cursor
when a window is busy is a familiar example of a wait situation.
We have given you a framework of how the Oracle9i database is
put together and what pieces play what role. Each component in the software
equation may not be all that important on its own; bring all of them together
and you have a powerful, robust, and fast database management system i.e.
Oracle9i.
101/117
Oracle
pl/sql programming
USER MANAGEMENT
The Oracle database has several layers of
security and gives you the ability to Audit each level.
Security Capabilities
Oracle makes several levels of security
available to the DBA.
Account Security
In order to access data in an Oracle database,
you must have access to an account in that data base. Each
account must have a password associated with it. A database
account can also be tied to an operating system account.
Passwords are set for a user when the users account is
created and may be altered after the account is created.
A users ability to alter the account password
will be limited by the tools to which the user is granted access.
The data base stores an encrypted version of the password in
a Data Dictionary table. If the account is directly related to an
OS account, it is possible to by-pass the password check and
rely on the operating system authentication instead.
The passwords can expire and the DBA can
establish the conditions under which a password can be reused in a database setting for password history. You can use
profiles to enforce standards for the passwords and can
automatically lock accounts, if there are multiple consecutive
failure to connect to the account.
Object Privileges
102/117
Oracle
pl/sql programming
103/117
Oracle
pl/sql programming
Password
Account
expire
lock /unlock;
Parameter
Username
Password
usage
- Name of the schema
-Password for the account, may
also be tied directly to the
OperatingSystem host
account name.
-For host-based authentication use
Identified externally.
- Identified Globally as for network
based authentication.
Default Tablespace
- Objects created in this scheme
are stored .
- This setting does not give the
user, right to create objects. It
only sets a default value
Temporary Tablespace - The table space in which
temporary segments are used
during sorting transactions Quota (on table
space)
- Allows the user to store objects
in the specified Tablespace upto
the total size specified as quota.
Profiles
- Assigns a profile to the user. If
none is specified, then the
Default profile is used. Profiles are
used to restrict the usage of
System resources and to enforce
password management rules.
Password
Account
NOTE:
Oracle
pl/sql programming
ALTER USER
Modify the security settings for an existing
database user, to change the options associated with that
user. Options that can be changed through the Alter user
command are:
Password
OS Authentication
Default tablespace
Temporary tablespace
Quota for Tablespace
Profile
Default Roles
username
105/117
Oracle
pl/sql programming
IDENTIFIED
by password / externally
DEFAULT TABLESPACE tablespace_name
TEMPORARY TABLESPACE tablespace_name
QUOTA integer / unlimited ON tablespace_name
DEFAULT ROLE role_name /All except role/
None;
WHERE :
Default Role
Default Role
Default Role
Default Role
Default Role
Oracle
pl/sql programming
DBA_PROFILES
DBA_TS_QUOTAS
USER_TS_QUOTAS
107/117
Oracle
pl/sql programming
SYNTAX
ALTER SYSTEM kill session integer1, integer2;
Where:
Kill session terminates a session
Integer1
- specifies the user sessionid
Integer2
-specifies the user serial number
-A user session is killed when the user is holding resources
urgently needed by another user, or when the DBA needs to
shut down the database.
-
instance
108/117
Oracle
pl/sql programming
CPU_PER_SESSION
hundredths
can use
CPU_PER_CALL
hundredths of
CONNECT_TIME
connected to
database.
IDLE_TIME
connected to
database without being
actively used.
FAILED_LOGIN_ATTEMPTS
attempts that
PASSWORD_LIFE_TIME
before
PASSWORD_REUSE_TIME
a password
used.
PASSWORD_REUSE_MAX
changed
password can be reused.
PASSWORD_LOCK_TIME
locked, if the
Login_ attempts
setting is exceeded.
PASSWORD_GRACE_TIME
during which a
can still be
when it has reached
password_life_time
settings
109/117
Oracle
pl/sql programming
110/117
Oracle
pl/sql programming
You can establish a maximum life time for a
password via the Password_ life_time resource, within
profiles. You can force users to change their passwords every
30 days as in the following example.
CREATE PROFILE limited_profile
LIMIT
PASSWORD_LIFE_TIME 30;
CREATE USER sam
Identified by john
PROFILE limited_profile;
Each account that uses limited_ profile will
have its password expire after30 days. If you password has
expired, you must change it the next time you login, unless the
profile has a specified grace period for expired password. An
expired account requires manual intervention by the DBA, to
be re-enabled.
ALTER USER sam PASSWORD expire;
- when sam attempts to connect to his account next time, he is
immediately prompted for a new password for the account.
You can also force users to change their password
when they first access their account via the password expire
clause of the create user command.
To see the password expiration date of any
account, query the expiry_date column of the DBA_USERS
data dictionary and USER_USERS expiry- date column to see
the password expiration date of the account of the current
user.
PRIVILEGES
You can grant users privileges to access the
database and objects within the database and allow them
specific system privileges.
Privilege Type
1.
SystemPrivileges
111/117
Oracle
pl/sql programming
A privilege or a right to perform a particular action
or to perform a particular action on a particular type of object
2.
Object Privileges
112/117
Oracle
pl/sql programming
With Admn Option Allows the grantee to grant the system
Privilege or role to other users or
roles.
- Grants made with Admin option are not
hierarchical .
- Revoking a Grant with Admin option,
does not Cascade.
Display system Privileges
Example: List the system privileges that have been granted
By querying the view DBA_SYS_PRIVS.
SELECT * FROM DBA_SYS_PRIVS ;
Revoke system Privileges
Syntax:
REVOKE SYSTEM PRIVILEGE / ROLE
FROM USER /ROLE / PUBLIC;
Where
PUBLIC
Object Privileges
Allows users to perform a particular action on a
specific table, view, sequence or stored procedures by
granting them object privileges. The type of object privileges
vary from object to object. Different object privileges allow the
use of specific SQL statements.
Object Privilege
SELECT
UPDATE
ALTER
DELETE
EXECUTE
113/117
Oracle
pl/sql programming
INDEX
REFERENCES
- You can grant object privileges to users and roles with the
Grant command.
Syntax:
GRANT Object privilege / ALL [column]
ON Object TO user / Role / Public
WITH GRANT OPTION;
Where
Object Privilege
Column
granted.
-Only specify columns when granting
Insert, References or update
privilege.
ALL
ON
TO
PUBLIC
- grants to al users.
With grant
114/117
Oracle
pl/sql programming
Emi can grant the privilege to another user or role.
Display object privileges
Select * from DBA_TAB_PRIVS;
Helpful Data Dictionary views
DBA_TAB_PRIVS
Oracle
pl/sql programming
Role characteristics
Can consist of both system and object privileges.
Are not owned by anyone, not in any schema
May be granted to any user or role
Can be enabled or disabled for each authorized user.
Description of roles are stored in the data dictionary.
Create Roles
Define categories of privileges for particular
groups of users by creating roles containing those privileges.
Create a role for each application (Application role)
Create a role for each type of user (User role)
Can GRANT user and application roles to users.
Syntax:
CREATE ROLE Role_name not identified / identified BY
password / externally;
Where
Role name
Not identified
required
Identified
By password
specify
enable the role.
Externally
on operating
116/117
Oracle
pl/sql programming
Grant create session, create any Table to
Manager;
Grant Manager to Emi;
Establish Default Roles
ALTER USER Username
DEFAULT ROLE rolename / all / all except
role_name /none;
- Default role :
-
*********************
117/117