Documente Academic
Documente Profesional
Documente Cultură
PL / SQL
STRUCTURE
2.1 INTRODUCTION
2.1.1 Performance
2.1.2 Portability
2.1.3 What PL/SQL can do for Programmer?
2.10 CURSORS
2.10.1 Explicit Cursor Management
2.10.2 Explicit Cursor Attributes
2.11 EXCERCISES
2.12 ANSWERS
2.1 INTRODUCTION:
SQL is a natural language of the DBA. It does not have any procedural capabilities such
as looping and branching. For this, Oracle provides the PL/SQL language.
PL/SQL is really an extension of SQL. PL/SQL adds to the power of SQL and provides
the user with all the facilities of a programming environment. PL/SQL is a procedural language
that ORACLE developed as an extension to standard SQL in order to provide a way to execute
procedural logic on the database.
PL/SQL bridges the gap between database technology and procedural programming
languages. It can be thought of as a development tool that extends the facilities of ORACLEs
SQL database language. Programmers can use it to create programs for validation and
manipulation of table data. Via PL/SQL he can insert, delete, update and retrieve table data as
well as use procedural techniques such as writing loops or branching to another block of code. It
allows him to use all the SQL data manipulation statements as well as transaction processing and
cursor control operations. PL/SQL blocks can contain any numbers of SQL statements. It allows
you to logically group a number of SQL sentences and parse them to DBA as a single block.
2.1.1 PERFORMANCE:
Without PL/SQL the DBA has to process SQL statements one at a time. This results in
calls being made to the DBA each time an SQL statement is executed. It slow downs table data
processing considerably. With a PL/SQL, an entire block of statements can be sent to the
RDBMS engine at any one time. It reduces the traffic on the network.
PL/SQL can also be used in SQL* forms. Its procedural capabilities can be used for
writing complex triggers that will validate data before it is placed in the table.
2.1.2 PORTABILITY:
Applications written in PL/SQL are portable to any computer hardware and operating
system. Where ORACLE is operational, hence PL/SQL code blocks written for the DOS version
of ORACLE will run on its Unix version, without any modifications made to it.
PL/SQL offers procedural methods of code writing for accessing the database and
manipulating the data with flexibility and ease. This is because PL/SQL supports the following.
PL/SQL allows you to declare variables and then use them in blocks of code. It is quite
possible to use variables to store the results of a query for later processing or calculate values and
insert them into an ORACLE table later. PL/SQL variable can be used anywhere, either in SQL
statements or in PL/SQL blocks.
This section provides an overview of PL/SQL program structure, data types, operators,
functions, procedures, keywords and cursors etc.
2.2 THE PL/SQL SYNTAX:
DECLARE
Variable declarations
BEGIN
Program statements
EXCEPTION
WHEN exception THEN
Program Statements
END;
In the above PL/SQL block, block parts are logical. Blocks starts with DECLARATION
section in which memory variables and other oracle objects can be declared. The next section
contains SQL executable statements for manipulating table data by using the variables and
constants declared in the DECLARE section. EXCEPTIONS is the last sections of the PL/SQL
block which contains SQL and/or PL/SQL code to handle errors that may crop up during the
execution of the above code block. EXCEPTION section is optional.
Each block can contain other blocks, i.e. blocks can be nested. Blocks of the code cannot
be nested in the DECLARATION section.
PL/SQL uses the standard ASCII set. The basic character set includes the following.
Uppercase alphabets A to Z.
Lowercase alphabets a to z.
Numbers 0 to 9
Symbols () + - * / < > = ! ; : , . @
% # $ ^ & _ \ { } ? [ ]
Words used in a PL/SQL blocks are called lexical units. We can freely insert blank spaces
between lexical units in a PL/SQL blocks. The spaces have no effect on the PL/SQL block.
The ordinary symbols used in PL/SQL blocks are
( ) + - * / < > = ; % , [ ] :
Compound symbols used in PL/SQL block are
<> != -= ^= <= >= : = ** || << >>
2.2.3. VARIABLES
Variables may be used to store the result of a query or calculations. Variables must be
declared before being used. Variables in PL/SQL block are named variables. A variable name
must begin with a character and can be followed by a maximum of 29 other characters (variable
length is 30 characters).
Reserved words cannot be used as variable names unless enclosed within the double
quotes. Variables must be separated from each other by at least one space or by a punctuation
mark.
The case (upper/lower) is insignificant when declaring variable names. Space cannot be
used in a variable name.
2.2.4. LITERALS
A literal is a numeric value or a character string used to represent itself. So, literals can be
classified into two types.
Numeric literals
Non- numeric literals (string literals)
Numeric literals:
These can be either integers or floating point numbers. If a float is being represented,
then the integer part must be separated from the float part by a period ( . ).
2.2.5. COMMENTS
A comment line begins with a double hyphen (--). In this case the entire
line will be treated as a comment.
Ex: -- This section performs salary updation.
The comment line begins with a slash followed by an asterisk (/*) till the
occurrence of an asterisk followed by a slash (*/). In this case comment
lines can be extended to more than one lines.
Ex-1: /* this is only for user purpose
which calculates the total salary temporarily
and stores the value in temp_sal */
PL/SQL supports the standard ORACLE SQL data types. The default data types that
can be declared in PL/SQL are
BOOLEAN: This data type stores only TRUE, FALSE or NULL values.
Syntax: variable name BOOLEAN
Ex: flag BOOLEAN.
%TYPE declares a variable or constant to have the same data type as that of a
previously defined variable or of a column in a table or in a view.
NOT NULL causes creation of a variable or a constant that cannot have a NULL value.
If you attempt to assign the value NULL to a variable or a constant that has been assigned a NOT
NULL constraint, causes an error.
NOTE: As soon as a variable or constant has been declared as NOT NULL, it must be
assigned a value. Hence every NOT NULL declaration of a variable or constant needs to be
followed by PL/SQL expression that loads a value into the variable or constant declared.
A value can be assigned to the variable in any one of the following two ways.
Using the assignment operator :=
Ex: tax := price * tax_rate
pay := basic + da.
Selecting or fetching table data values in to variables.
Ex: SELECT sal INTO pay
FROM Employee
WHERE emp_name = SMITH;
Declaring a constant is similar to declaring a variable except that you have to add
the key word CONSTANT and immediately assign a value to it. Thereafter, no further
assignment to the constants is possible.
Ex: pf_percent CONSTANT NUMBER (3,2) := 8.33;
The basic building block of a table is a cell (i.e. tables column). While creating a
table user attaches certain attributes like data type and constraints. These attributes can be passed
on to the variables being created in PL/SQL. This simplifies the declaration of variables and
constants.
For this purpose, the %TYPE attribute is used in the declaration of a variable when
the variables attributes must be picked from a table field (i.e. column).
In the above example, current_sal is the variable of PL/SQL block. It gets the data type
and constraints of the column (field) sal belong to the table Employee. Declaring a variable
with the %TYPE attribute has two advantages
You do not need to know the data type of the table column
If you change the parameters of the table column, the variables parameters will
change as well.
PL/SQL allows you to use the %TYPE attribute in a nesting variable declaration. The
following example illustrates several variables defined on earlier %TYPE declarations in a
nesting fashion.
Ex: Dept_sales INTEGER;
Area_sales dept_sales %TYPE0;
Group_sales area_sales %TYPE;
Regional_sales area_sales %TYPE;
Corporate_sales regional_sales %TYPE;
In case, variables for the entire row of a table need to be declared, then instead
of declaring them individually, %ROWTYPE is used.
Ex: emp_row_var employee %ROWTYPE;
Here, the variable emp_row_var will be a composite variable, consisting of the column
names of the table as its member. To refer to a specific, say sal; the following statement
will be used.
emp_row_var.sal := 5000;
The name of any ORACLE object (variable, memory variable, constant, record,
cursor etc) is known as an Identifier. The following laws have to be followed while working
with identifiers.
An identifier cannot be declared twice in the same block
The same identifier can be delcared in two different blocks.
In the second law, the two identifiers are unique and any change in one does not affect the
other.
Operators are the glue that holds expressions together. PL/SQL operators can be divided into
the following categories.
Arithmetic operators
Comparison operators
Logical operators
String operators
PL/SQL operators are either unary (i.e. they act on one value/variable) or binary (they act on
two values/variables)
+ Addition
- Subtraction or Negation ( Ex: -5)
* Multiplication
/ Division
** Exponentiation operator (example 10**5 = 10^5)
Comparison operators return a BOOLEAN result, either TRUE or FALSE. They are
Ex-1: new%matches with newyork, newjersey etc (i.e. any string beginning with
the word new).
Ex-2: _ _ _day matches with Sunday, Monday and Friday and It will not
match with other days like Tuesday, Wednesday, Thursday and
Saturday.
IN: Checks to see if a value lies within a specified list of values. The syntax is
Syntax: The_value [NOT] IN (value1, value2, value3)
PL/SQL has two operators specially designed to operate only on character string type
data. These are LIKE and ( || ) Concatenation operator. LIKE is a comparison operator and is
used to compare strings and it is discussed in the previous session. Concatenation operator has
following syntax.
Synatx: String_1 || string_2
String_1 and string_2 both are strings and can be a string constants, string variables or
string expressions. The concatenation operator returns a resultant string consisting of all the
characters in string_1 followed by all the characters in string_2.
NOTE-1: PL/SQL string comparisons are always case sensitive, i.e. aaa not equal to
AAA.
NOTE-2: ORACLE has some built in functions that are designed to convert from one
data type to another data type.
To_date: Converts a character string into date
To_number: Converts a character string to a number.
To_char: Converts either a number or date to character string.
Ex: To_date (1/1/92, mm/dd/yy/); Returns 01-jan-1992.
To_date (1-1-1998, mm-dd-yyyy); Returns 01/01/1998.
To_date (Jan 1, 2001,mm dd, yyyy); Returns Saturday, January 01, 2001.
To_date (1/1/02, mm/dd/rr); Returns Tue, Jan 01, 2002.
To_number (123.99, 999D99); Returns 123.99
To_number ( $1,232.95, $9G999D99); Returns $1, 232.99
To_char (123.99, 999D99); Returns 123.99.
The one or more PL/SQL statements can be written between the key words LOOP
and END LOOP. Once a LOOP begins to run, it will go on forever. Hence loops are
always accompanied by a conditional statements that keeps control on the number of
times it is executed. We can also build user defined exists from a loop, where required.
Ex: LOOP
Cntr : = cntr + 1;
IF cntr > 100
EXIT;
END IF;
END LOOP;
EXIT statement brings the control out of loop if the condition is satisfied.
EXIT WHEN statement enables you to specify the condition required to exit the execution
of the loop. In this case no if statement is required.
The GOTO statement allows you to change the flow of control within a PL/SQL
block. The syntax is as follows
Syntax: GOTO <label name> ;
The label is surrounded by double brackets ( << >>) and label must not have a semi
colon after the label name. The label name does not contain a semi colon because it is not a
PL/SQL statement. But rather an identifier of a block of PL/SQL code. You must have at least
one statement after the label otherwise an error will result. The GOTO destination must be in the
same block, at the same level as or higher than the GOTO statement itself.
Ex: IF result = 'fail' THEN
GOTO failed_stud
END IF;
<<failed_stud>>
Message ('student is failed');
The entry point of the destination block is defined within << >> as shown
above, i.e. labels are written within the symbol << >>. Notice that <<failed_stud>> is a
label and it is not ended with semicolon ( ; ).
FOR loop will allow you to execute a block of code repeatedly until some
condition occurs. The syntax of FOR loop is as follows.
Syntax: FOR loop_index IN [ REVERSE] low_value .. High_value LOOP
Statements to execute
END LOOP;
The loop_index is defined by oracle as a local variable of type integer. REVERSE
allows you to execute the loop in reverse order. The low_value .. High_value is the range
to execute the loop. These can be constants or variables. The line must be terminated with
loop with no semicolon at the end of this line. You can list the statements to be executed
until the loop is executed is evaluated to false.
We can terminate the FOR loop permanently using EXIT statement based on
some BOOLEAN condition. Nesting of FOR loop can also be allowed in PL/SQL. The
outer loop executed once, then the inner loop is executed as many times as the range
indicates, and then the control is returned to the outer loop until its range expires.
Let us discuss some examples from the understanding how to write a PL/SQL
block structure. Here we assume that a table called "EMP" is created and the datas are
already inserted into it.
DECLARE
num NUMBER (3);
sal emp.salary %TYPE;
emp_name emp.name %TYPE;
count NUMBER (2) : = 1;
starting_emp CONSTANT NUMBER(3) : = 134;
BEGIN
SELECT name, salary INTO emp_name, sal
FROM EMP
WHERE emp_no = starting_emp;
WHILE sal < 4000.00
LOOP
Count : = count + 1;
In the above example there are five statements in the declaration part. The num is
a integer type, sal and emp_name takes the similar data type of the salary and name
columns of EMP table respectively. Count is a variable of type integer and takes initial
value 1. Starting_emp is a constant and it is of integer type with immediately assigned
value 134.
Between BEGIN and END key words, there are some SQL executable statements
used for manipulating the table data. The SELECT statement extracts data stored in name
and salary columns of EMP table corresponding to the employee having employee
number 134. It stores those values In the variables emp_name and sal respectively.
If sal less than 4000 then the statements within the loop will be executed. Within
the loop, there are two SQL statements, the first one increments the count value by 1 and
the second statement is a SELECT statement. The commit statement commits the changes
made to that table. The END statement terminates the PL/SQL block.
EXAMPLE-2:
This example assumes the existence of table accounts created by using the
following SQL statements.
PL/SQL block:
DECLARE
acct_balance NUMBER(6,2);
acct CONSTANT NUMBER(3) : = 312;
debit_amt CONSTANT NUMBER(5,2) : = 500.00;
BEGIN
SELECT bal INTO acct_balance FROM Accounts
WHERE accnt_id = acct;
IF acct_balance = debit_amt THEN
UPDATE Accounts
SET bal : = bal - debit_amt WHERE accnt_id = acct;
ELSE
Message ('insufficient amount in account');
END IF;
END;
The above example illustrates the use of IF .. THEN .. ELSE.. END IF condition
control statements.
Declaration part declares one variable and two constants. The SELECT
statement extracts the amount in the bal column of Accounts table corresponding to
account number 312, and stores that in a variable acct_balance.
EXAMPLE-3:
This example assumes two tables, which are created by following statements.
PL/SQL block :
DECLARE
num_in_stack NUMBER(5);
BEGIN
SELECT quantity INTO num_in_stack
FROM Inventory WHERE product = 'gasket';
IF num_in_stack > 0 THEN
UPDATE Inventory SET quantity : = quantity - 1
WHERE product = 'gasket';
INSERT INTO Purchase_record
VALUES (' One gasket purchased', sysdate);
ELSE
INSERT INTO Purchase_record
VALUES ('no gasket availabel',sysdate);
Message ( 'there are no more gasket in stack' );
END IF;
Commit;
END;
PL/SQL has the capability of dealing with the errors that arise while executing a
PL/SQL block of code. It has a number of conditions that are pre programmed in to it that
are recognized as error conditions. These are called internally defined exceptions. You can
also program PL/SQL to recognize user-defined exceptions.
User can write a set of code, which is to be executed while error occurs when
executing a PL/SQL block of code. These set of code are called user-defined exceptions,
and these are placed in the last section of PL/SQL block called EXCEPTIONS.
The method used to recognise user-defined exceptions is as follows
RAISE statement acts like CALL statement of high level languages. It has general format
RAISE < name of exception >
When RAISE statement is executed, it stops the normal processing of PL/SQL block
of code and control passes to an error handler block of the code at the end of PL/SQL
program block ( EXCEPTION section ).
An exception declaration declares a name for user defined error conditions that the
PL/SQL code block recognizes. It can only appear in the DECLARE section of the PL/SQL code
which preceedes the key word BEGIN.
EXAMPLE :
DECLARE
---------------
zero_commission Exception;
---------------
BEGIN
-----------------
IF commission = 0 THEN
RAISE zero_commission;
------------------------
EXCEPTION
WHEN zero_commission THEN
Process the error
END;
Exception handler (error handler block ) is written between the key words EXCEPTION
and END. The exception handling part of a PL/SQL code is optional. This block of code
specifies what action has to be taken when the named exception condition occurs.
The naming convention for exception name are exactly the same as those for variables or
constants. All the rules for accessing an exception from PL/SQL blocks are same as those for
variables and constants. However, it should be noted that exceptions cannot be passed as
arguments to functions or procedures like variables or constants.
It is possible to use WHEN OTHERS clause in the exception handling part of the
PL/SQL block. It will take care of all exceptions that are not taken care of in the code.
The syntax for exception handling portion of PL/SQL block is as follows:
EXCEPTION
WHEN exception_1 THEN Statements;
WHEN exception_2 THEN Statements;
- - --- ---- -- ---
END;
In this syntax, exception_1 and exception_2 are the names of exceptions (may be
predefined or user-defined ). Statements in the PL/SQl code that will be executed if the exception
name is satisfied.
EXAMPLE-1:
This example writes PL/SQL code for validating accnt_id of Accounts table so that it
must not be left blank, if it is blank cursor should not be allowed to move to the next field.
DECLARE
no_value exception;
BEGIN
IF : Accounts.accnt_id IS NULL THEN
RAISE no_value;
ELSE
next_field;
END IF;
EXCEPTION
WHEN no_value THEN
Message ( 'account id cannot be, blank Please enter valid data !!! ' );
go_field ( : system.cursor_field );
END;
In the above example accnt_id field of Accounts table is checked for NULL value. If it is
NULL, then RAISE statement calls exception handler no_value. This exception name no_value
is declared in DECLARE section and defined in the EXCEPTION section of PL/SQL block by
using WHEN statement. no_value is a user-defined exception.
EXAMPLE-2:
DECLARE
balance Accounts.bal %TYPE;
acount_num Accounts.accnt_id %TYPE;
BEGIN
SELECT accnt_id bal INTO account_num, balance
FROM Accounts WHERE accnt_id > 0000;
EXCEPTION
WHEN no_data_found THEN
Message ('empty table');
END;
In the above example exception is used in the PL/SQL block. This exception is
predefined internal PL/SQL exception (NO_DATA_FOUND).
Therefore, it does not require declaration in DECLARE section and RAISE statement in
BEGIN END portion of the block. Even though it is not raised, the ORACLE server will raise
this exception when there is no data in bal and accnt_id field.
PL/SQL allows you to define functions and procedures. These are similare to functions
and procedures defined in any other languages, and they are defined as one PL/SQL block.
2.8.1 FUNCTIONS :
The syntax for defining a function is as follows :
FUNCTION name [ (argument-list) ] RETURN data-type {IS, AS}
Variable-declarations
BEGIN
Program-code
[ EXCEPTION
error-handling-code]
END;
In this syntax,
name The name you want to give the function.
argument-list List of input and/or output parameters for the functions.
data-type. The data type of the function's return value.
Variable-declarations Where you declare any variables that are local to the function.
program-code Where you write PL/SQL statements that make up the function.
error-handling-code Where you write any error handling routine.
Notice that the function block is similar to the PL/SQL block that we discussed earlier.
The keyword DECLARE has been replaced by FUNCTION header, which names the
function, describes the parameter and indicates the return type.
Check ( 2 > 1, 1 , 0)
Check (5 = 0, 1, 0)
2.8.2 PROCEDURES:
The declaration of procedures is almost identical to that of function and the syntax
is given below.
PROCEDURE name [(argument list)] {IS,AS}
Variable declaration
BEGIN
Program code
[EXCEPTION
Error handling code ]
END;
Here name is the name that you want to give the procedure and all other are similar to
function declaration. Procedure declaration resembles a function declaration except that there is
no data type and key word PROCEDURE is used instead of FUNCTION.
A trigger is a data base object, like a table or an index. When you define a trigger, it
becomes a part of the database and it is always is executed when the event for which it is defined
occurs.
2.10 CURSORS :
PL/SQL cursors provide a way for your program to select multiple rows of data from the
database and then to process each row individually. Cursors are PL/SQL constructs that enable
you to process, one row at a time, the results of a multi row query.
ORACLE uses work areas to execute SQL statements, PL/SQL allows user to name
private work areas and access the stored information. The PL/SQL constructs to identify each
and every work area used by SQL is called a Cursor.
Implicit cursors
Explicit cursors
Implicit cursors are declared by ORACLE for each UPDATE, DELETE and INSERT
SQL commands. Explicit cursors are declared and used by the user to process multiple row,
returned by SELECT statement.
The set of rows returned by a query is called the Active Set. Its size depends on the
number of rows that meet the search criteria of the SQL query. The data that is stored in the
cursor is called the Active Data Set.
ORACLE cursor is a mechanism used to easily process multiple rows of data. Cursors
contain a pointer that keeps track of current row being accessed, which enables your program to
process the rows at a time.
EXAMPLE:
The following are the steps to using explicitly defined cursors within PL/SQL
Declare the cursor
Open the cursor
Fetch data from the cursor
Close the cursor
Opening a cursor:
Opening a cursor executes the query and identifies the active set that contains all the
rows, which meet the query search criteria.
Syntax :
OPEN cursor_name
Ex:
OPEN c_name
Open statement retrieves the records from the database and places it in the cursor (private
SQL area).
Closing a cursor :
Closing statement closes/deactivates/disables the previously opened cursor and makes the active
set undefined. Once it is closed, you cannot perform any operations on it. Once a cursor is closed, the
user can reopen the cursor by using Open statement.
EXAMPLE-1 :
The HRD manager has decided to raise the salary for all the employees in the physics
department by 0.05. whenever any such raise is given to the employees, a record for the same is
maintained in the emp_raise table ( the data table definitions are given below ). Write a PL/SQL
block to update the salary of each employee and insert the record in the emp_raise table.
Tabe: employee
emp_code varchar (10)
emp_name varchar (10)
dept varchar (15)
job varchar (15)
salary number (6,2)
Table: emp_raise
emp_code Varchar(10)
raise_date Date
raise_amt Number(6,2)
Solution:
DECLARE
CURSOR c_emp IS
SELECT emp_code, salary FROM employee
WHERE dept = 'physics';
str_emp_code employee.emp_code %TYPE;
num_salary employee.salary %TYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO str_emp_code, num_salary;
UPDATE employee SET salary : = num_salary + (num_salary * 0.05)
WHERE emp_code = str_emp_code;
INSERT INTO emp_raise
VALUES ( str_emp_code, sysdate, num_salary * 0.05 );
END LOOP;
Commit;
CLOSE c_emp;
END;
%NOT FOUND: Evaluates to TRUE if the last fetch is failed i.e. no more rows are left.
Syntax: cursor_name %NOT FOUND
%FOUND: Evaluates to TRUE, when last fetch succeeded
Syntax: cursor_name %FOUND
%ISOPEN: Evaluates to TRUE, if the cursor is opened, otherwise evaluates to
FALSE. Syntax: cursor_name %ISOPEN
%ROWCOUNT: Returns the number of rows fetched.
Syntax: cursor_name %ROWCOUNT.
EXAMPLE :
DECLARE
v_emp_name varchar2(32);
v_salary_rate number(6,2);
v_payroll_total number(9,2);
v_pay_type char;
CURSOR c_emp IS
SELECT emp_name, pay_rate, pay_type FROM employee
WHERE emp_dept = 'physics'
BEGIN
IF c_name %ISOPEN THEN
RAISE
not_opened
ELSE
OPEN c_emp;
LOOP
FETCH c_emp INTO v_emp_name, v_salary_rate, v_pay_type;
EXIT WHEN c_emp % NOTFOUND;
IF v_pay_type = 'S' THEN
v_payroll_total : = (v_salary_rate * 1.25 );
ELSE
v_payroll_total : = (v_salary_rate * 40);
END IF;
INSERT INTO weekly_salary VALUES ( 'v_payroll_total' );
END LOOP;
CLOSE c_emp;
EXCEPTION
WHEN not_opened
Message ( 'cursor is not opened' );
END;
REFERENCES:-
2.11 EXERCISE :
A. 1. False B. 1. Procedural.
2 . True 2. Words.
3. False 3. Query Calculations.
4. False 4. Integers Floating Point Numbers.
5. False 5. NOT NULL.
6. True 6. %TYPE.
7. False 7. **.
8. True 8. Exception.
9. False 9. Triggers.
10. False 10. Active data set.
11. Open Statement.
12. Open.