Unit IV Rdbms Notes
Unit IV Rdbms Notes
PL/SQL
Brief History of PL/SQL
• PL/SQL is Oracle's procedural language extension to SQL, the non-procedural
relational database language.
• With PL/SQL, you can use SQL statements to manipulate ORACLE data and the flow
of control statements to process the data. Moreover, you can declare constants and
variables, define subprograms (procedures and functions), and trap runtime errors.
Thus, PL/SQL combines the data manipulating power of SQL with the data
processing power of procedural languages.
• Many Oracle applications are built using client-server architecture. The Oracle
database resides on the server.
• The program that makes requests against this database resides on the client machine.
• This program can be written in C, Java, or PL/SQL.
• While PL/SQL is just like any other programming language, it has syntax and rules
that determine how programming statements work together. It is important for you to
realize that PL/SQL is not a stand-alone programming language.
• PL/SQL is a part of the Oracle RDBMS, and it can reside in two environments, the
client and the server.
• As a result, it is very easy to move PL/SQL modules between server-side and client-
side applications.
• When the PL/SQL engine is located on the server, the whole PL/SQL block is passed
to the PL/SQL engine on the Oracle server.
• The PL/SQL engine processes the block according to the below Figure .
• When the PL/SQL engine is located on the client, as it is in the Oracle Developer
Tools, the PL/SQL processing is done on the client side.
• All SQL statements that are embedded within the PL/SQL block are sent to the
Oracle server for further processing. When PL/SQL block contains no SQL statement,
the entire block is executed on the client side.
PL/SQL BLOCKS
• PL/SQL blocks can be divided into two groups:
1. Named and
2. Anonymous.
• Named blocks are used when creating subroutines. These subroutines are procedures,
functions, and packages.
• The subroutines can be stored in the database and referenced by their names later on.
• In addition, subroutines can be defined within the anonymous PL/SQL block.
• Anonymous PL/SQL blocks do not have names. As a result,they cannot be stored in
the database and referenced later.
• PL/SQL blocks contain three sections
1. Declare section
2. Executable section and
3. Exception-handling section.
• The executable section is the only mandatory section of the block.
PL/SQL block has the following structure:
DECLARE
Declaration statements
BEGIN
Executable statements
EXCETION
Exception-handling statements
END ;
Both the declaration and exception-handling sections are optional.
DECLARATION SECTION
The declaration section is the first section of the PL/SQL block.It contains definitions of
PL/SQL identifiers such as variables, constants, cursors and so on.
Example
DECLARE
v_first_name VARCHAR2(35) ;
v_last_name VARCHAR2(35) ;
v_counter NUMBER := 0 ;
EXECUTABLE SECTION
• The executable section is the next section of the PL/SQL block.
• This section contains executable statements that allow you to manipulate the variables
that have been declared in the declaration section.
BEGIN
SELECT first_name, last_name
INTO v_first_name, v_last_name
FROM student
WHERE student_id = 123 ;
DBMS_OUTPUT.PUT_LINE
(‘Student name :’ || v_first_name ||‘ ’|| v_last_name);
END;
EXCEPTION-HANDLING SECTION
• The exception-handling section is the last section of the PL/SQL block.
• This section contains statements that are executed when a runtime error occurs within
a block.
• Runtime errors occur while the program is running and cannot be detected by the
PL/SQL compiler.
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE
(‘ There is no student with student id 123 ’);
END;
Fundamenals of PL/SQL
Reserved Words
Literals
A literal is an explicit numeric, character, string, or BOOLEAN value not represented by an
identifier.
Topics:
Numeric Literals
Character Literals
String Literals
BOOLEAN Literals
Date and Time Literals
Single-Line Comments
A single-line comment begins with --. It can appear anywhere on a line, and it extends to the
end of the line.
SQL> DECLARE
2 howmany NUMBER;
3 num_tables NUMBER;
4 BEGIN
5 -- Begin processing
6 SELECT COUNT(*) INTO howmany
7 FROM USER_OBJECTS
8 WHERE OBJECT_TYPE = 'TABLE'; -- Check number of tables
9 num_tables := howmany; -- Compute some other value
10 END;
11 /
Multiline Comments
A multiline comments begins with /*, ends with */, and can span multiple lines.
SQL> DECLARE
2 some_condition BOOLEAN;
3 pi NUMBER := 3.1415926;
4 radius NUMBER := 15;
5 area NUMBER;
6 BEGIN
7 /* Perform some simple tests and assignments */
8 IF 2 + 2 = 4 THEN
9 some_condition := TRUE;
10 /* We expect this THEN to always be performed */
11 END IF;
Data Types:
PL/SQL has two kinds of data types: scalar and composite. The scalar types are types that
store single values such as number, Boolean, character, and datetime whereas the composite
types are types that store multiple values, for example, record and collection.
Number
Boolean
Character
Datetime
A scalar data type may have subtypes. A subtype is a data type that is a subset of another data
type, which is its base type. A subtype further defines a base type by restricting the value or
size of the base data type.
CHA
R :This data type stores the string value, and the size of the string is fixed at the time of declaring
the variable.Oracle would be blank-padded the variable if the variable didn't occupy the entire
size that has been declared for it, Hence Oracle will allocate the memory for declared size even
if the variable didn't occupy it fully.The size restriction for this data type is 1-2000
bytes.CHAR data type is more appropriate to use where ever fixed the size of data will be
handled.
Example:
grade CHAR;
manager CHAR (10):= 'guru99';
VARCHAR :This data type stores the string, but the length of the string is not fixed.
2
The size restriction for this data type is 1-4000 bytes for table column size and 1-32767
bytes for variables.
The size is defined for each variable at the time of variable declaration.
But Oracle will allocate memory only after the variable is defined, i.e., Oracle will
consider only the actual length of the string that is stored in a variable for memory
allocation rather than the size that has been given for a variable in the declaration part.
It is always good to use VARCHAR2 instead of CHAR data type to optimize the
memory usage.
Example:
manager VARCHAR2(10) := ‘guru99'
This data type stores fixed or floating point numbers up to 38 digits of precision. This data
type is used to work with fields which will contain only number data. The variable can be
declared either with precision and decimal digit details or without this information. Values
need not enclose within quotes while assigning for this data type.
A NUMBER(8,2);
B NUMBER(8);
C NUMBER;
Syntax Explanation:
In the above, the first declaration declares the variable 'A' is of number data type with
total precision 8 and decimal digits 2.
The second declaration declares the variable 'B' is of number data type with total
precision 8 and no decimal digits.
The third declaration is the most generic, declares variable 'C' is of number data type
with no restriction in precision or decimal places. It can take up to a maximum of 38
digits.
This data type stores the logical values. It represents either TRUE or FALSE and mainly used
in conditional statements. Values need not enclose within quotes while assigning for this data
type.
Var1 BOOLEAN;
Syntax Explanation:
In the above, variable 'Var1' is declared as BOOLEAN data type. The output of the
code will be either true or false based on the condition set.
This data type stores the values in date format, as date, month, and year. Whenever a variable
is defined with DATE data type along with the date it can hold time information and by
default time information is set to 12:00:00 if not specified. Values need to enclose within
quotes while assigning for this data type.
The standard Oracle time format for input and output is 'DD-MON-YY' and it is again set at
NLS_PARAMETERS (NLS_DATE_FORMAT) at the session level.
newyear DATE:='01-JAN-2015';
current_date DATE:=SYSDATE;
Syntax Explanation:
In the above, variable 'newyear' is declared as DATE data type and assigned the value
of Jan 1st, 2015 date.
The second declaration declares the variable current_date as DATE data type and
assigned the value with current system date.
Both these variable holds the time information.
DECLARE
a integer := 10;
b integer := 20;
c integer;
f real;
BEGIN
c := a + b;
dbms_output.put_line('Value of c: ' || c);
f := 70.0/3.0;
dbms_output.put_line('Value of f: ' || f);
END;
/
When the above code is executed, it produces the following result −
Value of c: 30
Value of f: 23.333333333333333333
PL/SQL procedure successfully completed.
Anchored data types are those data type which you assign to a variable based on a database
object. They are called anchored data type because unlike the variable data type it is not
dependent on that of any underlying object.
Syntax
Variable-name typed-attribute%type
Declare
tot_sales NUMBER(20,2);
-- Anchor to a PL/SQL variable.
monthly_sales tot_sales%TYPE;
Bind variables
• Bind variables in Oracle database can be defined as the variables that we create in
SQL* PLUS and then reference in PL/SQL.
• How To Declare a Bind Variable (Variable command)
We can declare a bind variable using VARIABLE command. Variable command declares
the bind variable which you can refer in PL/SQL.
Example
• VARIABLE v_bind1 VARCHAR2 (10);
Restriction
• If you are creating a bind variable of NUMBER datatype then you can not specify the
precision and scale.
Substitution Variables
Are used to get user input at run time. Are referenced within a PL/SQL block with a
preceding ampersand . Are used to avoid hard-coding values that can be obtained at run time
Printing in PL/SQL
Oracle does have a built-in-package called DBMS-OUTPUT with the procedure PUT_LINE
to print. An environment variable named SERVEROUTPUT must be toggled ON to view
output from it.
The DBMS_OUTPUT is the most frequently used package because of its capabilities to get
lines from a file and to put lines into the buffer.
The PUT-LINE procedure displays information passed to the buffer and puts a new line
marker at end.
Example
DBMS_OUTPUT.PUT_LINE(‘This line will be displayed’);
The maximum size of the buffer is 1 megabyte. The following command enables you to view
information from the buffer by using the DBMS_OUTPUT package and also sets the buffer
size to the number of bytes specified.
SET SERVEROUTPUT ON[on size 10000];
CONTROL STRUCTURES
There are three basic programming control structures
1. Sequential structure- A series of instruction are performed from the beginning to the
end in a linear order.
2. Selection structure-Also known as decision structure. It involves conditions with a
true or false outcome. Based on the outcome , one of the options is performed, and the
other option is skipped.
3. Looping structure- A series of instructions is performed repeatedly. There are
different looping statements for a variety of situations.
Selection structure
There are three selection or conditional statements in PL/SQL.
IF-THEN Statement
THEN-ELSE Statement
IF-THEN-ELSIF Statement
CASE Statement
IF-THEN Statement
IF condition THEN
sequence_of_statements
END IF;
The second form of IF statement adds the keyword ELSE followed by an alternative
sequence of statements, as follows:
IF condition THEN
sequence_of_statements1
ELSE
sequence_of_statements2
END IF;
The sequence of statements in the ELSE clause is executed only if the condition is
false or null. Thus, the ELSE clause ensures that a sequence of statements is
executed. In the following example, the first UPDATE statement is executed when the
condition is true, but the second UPDATE statement is executed when the condition is
false or null:
IF trans_type = 'CR' THEN
UPDATE accounts SET balance = balance + credit WHERE ...
ELSE
UPDATE accounts SET balance = balance - debit WHERE ...
END IF;
IF-THEN-ELSIF Statement
If the first condition is false or null, the ELSIF clause tests another condition.
An IF statement can have any number of ELSIF clauses; the final ELSE clause is
optional. Conditions are evaluated one by one from top to bottom. If any condition
is true, its associated sequence of statements is executed and control passes to the
next statement. If all conditions are false or null, the sequence in the ELSE clause is
executed. Consider the following example:
BEGIN
...
IF sales > 50000 THEN
bonus := 1500;
ELSIF sales > 35000 THEN
bonus := 500;
ELSE
bonus := 100;
END IF;
INSERT INTO payroll VALUES (emp_id, bonus, ...);
END;
CASE Statement
Like the IF statement, the CASE statement selects one sequence of statements to
execute. However, to select the sequence, the CASE statement uses a selector rather
than multiple Boolean expressions. To compare the IF and CASE statements,
consider the following code that outputs descriptions of school grades:
IF grade = 'A' THEN
dbms_output.put_line('Excellent');
ELSIF grade = 'B' THEN
dbms_output.put_line('Very Good');
ELSIF grade = 'C' THEN
dbms_output.put_line('Good');
ELSIF grade = 'D' THEN
dbms_output. put_line('Fair');
ELSIF grade = 'F' THEN
dbms_output.put_line('Poor');
ELSE
dbms_output.put_line('No such grade');
END IF;
Notice the five Boolean expressions. In each instance, we test whether the same
variable, grade, is equal to one of five values: 'A', 'B', 'C', 'D', or 'F'. Let us
rewrite the preceding code using the CASE statement, as follows:
CASE grade
WHEN 'A' THEN dbms_output.put_line('Excellent');
WHEN 'B' THEN dbms_output.put_line('Very Good');
WHEN 'C' THEN dbms_output.put_line('Good');
WHEN 'D' THEN dbms_output.put_line('Fair');
WHEN 'F' THEN dbms_output.put_line('Poor');
ELSE dbms_output.put_line('No such grade');
END CASE
Looping Structure
A FOR LOOP is a repetition control structure that allows you to efficiently write a loop
that needs to execute a specific number of times.
Syntax
If the condition is FALSE before entering the loop, the WHILE loop does not execute at all.
This behavior is different from the LOOP statement whose loop body always executes once.
To terminate the loop prematurely, you use an EXIT or EXIT WHEN statement.
Counter : 1
Counter : 2
Counter : 3
Counter : 4
Counter : 5
In this example:
Counter : 1
Counter : 2
The condition in the EXIT WHEN clause evaluated to true when the counter is three.
Therefore, the loop body only executed two times before it terminated.
In this tutorial, you have learned how to use the PL/SQL WHILE loop statement to execute a
sequence of statements as long as a specified condition is TRUE.
DML stands for Data Manipulation Language. These statements are mainly used to
perform the manipulation activity. It deals with the below operations.
Data Insertion
Data Update
Data Deletion
Data Selection
In PL/SQL, we can do the data manipulation only by using the SQL commands.
Data Insertion
In PL/SQL, we can insert the data into any table using the SQL command INSERT INTO.
This command will take the table name, table column and column values as the input and
insert the value in the base table.
The INSERT command can also take the values directly from another table using 'SELECT'
statement rather than giving the values for each column. Through 'SELECT' statement, we
can insert as many rows as the base table contains.
Syntax:
BEGIN
INSERT INTO <table_name>(<column1 >,<column2>,...<column_n>)
VALUES(<valuel><value2>,...:<value_n>);
END;
The above syntax shows the INSERT INTO command. The table name and values are
a mandatory fields, whereas column names are not mandatory if the insert statements
have values for all the column of the table.
The keyword 'VALUES' is mandatory if the values are given separately as shown
above.
Data Update
Data update simply means an update of the value of any column in the table. This can be
done using 'UPDATE' statement. This statement takes the table name, column name and
value as the input and updates the data.
Syntax:
BEGIN
UPDATE <table_name>
SET <columnl>=<VALUE1>,<column2>=<value2>,<column_n>=<value_n>
WHERE <condition that uniquely identifies the record that needs to be update>;
END;
The above syntax shows the UPDATE. The keyword 'SET' instruct that PL/SQL
engine to update the value of the column with the value given.
'WHERE' clause is optional. If this clause is not given, then the value of the
mentioned column in the entire table will be updated.
Data Deletion
Data deletion means to delete one full record from the database table. The 'DELETE'
command is used for this purpose.
Syntax:
BEGIN
DELETE
FROM
<table_name>
WHERE <condition that uniquely identifies the record that needs to be update>;
END;
The above syntax shows the DELETE command. The keyword 'FROM' is optional
and with or without 'FROM' clause the command behaves in the same way.
'WHERE' clause is optional. If this clause is not given, then the entire table will be
deleted.
CURSOR
Types Of Cursors
IMPLICIT CURSOR
• Any given PL/SQL block issues an implicit cursor whenever an SQL statement is
executed, as long as an explicit cursor does not exist for that SQL statement.
• A cursor is automatically associated with every DML (Data Manipulation) statement
(UPDATE, DELETE, INSERT).
• All UPDATE and DELETE statements have cursors that identify the set of rows that
will be affected by the operation.
• An INSERT statement needs a place to receive the data that is to be inserted in the
database; the implicit cursor fulfills this need.
• The most recently opened cursor is called the “SQL%” Cursor.
• The implicit cursor is used to process INSERT, UPDATE, DELETE, and SELECT
INTO statements.
• During the processing of an implicit cursor, Oracle automatically performs the OPEN,
FETCH, and CLOSE operations.
• An implicit cursor cannot tell you how many rows were affected by an update. SQL
%ROWCOUNT returns numbers of rows updated. It can be used as follows:
BEGIN
UPDATE student
SET first_name = 'B'
WHERE first_name LIKE 'B%';
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT);
END;
EXPLICIT CURSOR
• The only means of generating an explicit cursor is for the cursor to be named in the
DECLARE section of the PL/SQL Block.
• The advantages of declaring an explicit cursor over the indirect implicit cursor are
that the explicit cursor gives more programmatic control to the programmer.
• Implicit cursors are less efficient than explicit cursors and thus it is harder to trap data
errors.
• The process of working with an explicit cursor consists of the following steps:
• DECLARING the cursor. This initializes the cursor into memory.
• OPENING the cursor. The previously declared cursor can now be opened; memory is
allotted.
• FETCHING the cursor. The previously declared and opened cursor can now retrieve
data; this is the process of fetching the cursor.
• CLOSING the cursor. The previously declared, opened, and fetched cursor must now
be closed to release memory allocation.
DECLARING A CURSOR
• Declaring a cursor defines the name of the cursor and associates it with a SELECT
statement.
• The first step is to Declare the Cursor with the following syntax:
• Cursor names follow the same rules of scope and visibility that apply to the PL/SQL
identifiers.
• Because the name of the cursor is a PL/SQL identifier, it must be declared before it is
referenced.
• Any valid select statement can be used to define a cursor, including joins and
statements with the UNION or MINUS clause.
OPEN cursor_name;
After the cursor has been declared and opened, you can then retrieve data from the
cursor.The process of getting the data from the cursor is referred to as fetching the
cursor.
There are two methods of fetching a cursor, done with the following command:
Example
DECLARE
CURSOR c_zip IS
SELECT *FROM zipcode;
vr_zip c_zip%ROWTYPE;
BEGIN
OPEN c_zipcode;
LOOP
FETCH c_zip INTO vr_zip;
EXIT WHEN c_zip%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(vr_zip.zipcode||‘ ’||vr_zip.city||‘ ’||vr_zip.state);
END LOOP;
3. CLOSING A CURSOR
• Once all of the rows in the cursor have been processed (retrieved), the cursor should
be closed.
• This tells the PL/SQL engine that the program is finished with the cursor, and the
resources associated with it can be freed.
CLOSE cursor_name;
• When using the cursor FOR LOOP, the process of opening, fetching, and closing are
implicitly handled.
• This makes the blocks much simpler to code and easier to maintain.
• The cursor FOR LOOP specifies a sequence of statements to be repeated once for
each row returned by the cursor.
• Use the cursor FOR LOOP if you need to FETCH and PROCESS each and every
record from a cursor.
Example
DECLARE
CURSOR c_student IS
SELECT student_id, last_name, first_name FROM student WHERE student_id < 110;
BEGIN
FOR r_student IN c_student
LOOP
INSERT INTO table_log VALUES(r_student.last_name);
END LOOP;
END;
• The CURSOR FOR UPDATE clause is only used with a cursor when you want to
update tables in the database.
• Generally, when you execute a SELECT statement, you are not locking any rows.
• The purpose of using the FOR UPDATE clause is to lock the rows of the tables that
you want to update, so that another user cannot perform an update until you perform
your update and release the lock.
• The next COMMIT or ROLLBACK statement releases the lock.
• The syntax is simply to add FOR UPDATE to the end of the cursor definition.
• If there are multiple items being selected, but you only want to lock one of them, then
end the cursor definition with the following syntax:
DECLARE
CURSOR c_stud_zip IS
SELECT s.studid_id, z.city FROM student s, zipcode zWHERE z.city = 'Brooklyn'
AND s.szip = z.zip
FOR UPDATE OF sphone;
BEGIN
FOR r_stud_zip IN c_stud_zip
LOOP
DBMS_OUTPUT.PUT_LINE(r_stud_zip.studid);
UPDATE student SET sphone = '718'||SUBSTR(sphone,4) WHERE
CURRENT OF c_stud_zip;
END LOOP;
END;
Exception Handling
PL/SQL provides a feature to handle the Exceptions which occur in a PL/SQL Block known
as exception Handling. Using Exception Handling we can test the code and avoid it from
exiting abruptly.
Types of Exception.
System exceptions are automatically raised by Oracle, when a program violates a RDBMS
rule. There are some system exceptions which are raised frequently, so they are pre-defined
and given a name in Oracle which are known as Named System Exceptions.
TOO_MANY_ROWS When you SELECT or fetch more than one row ORA-
into a record or variable. 01422
BEGIN
Execution section
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line ('A SELECT...INTO did not return any row.');
END;
Those system exception for which oracle does not provide a name is known as unamed
system exception. These exception do not occur frequently. These Exceptions have a code
and an associated message.
The general syntax to declare unnamed system exception using EXCEPTION_INIT is:
DECLARE
exception_name EXCEPTION;
PRAGMA
EXCEPTION_INIT (exception_name, Err_code);
BEGIN
Execution section
EXCEPTION
WHEN exception_name THEN
handle the exception
END;
For Example: Lets consider the product table and order_items table from sql joins.
Here product_id is a primary key in product table and a foreign key in order_items table.
If we try to delete a product_id from the product table when it has child records in order_id
table an exception will be thrown with oracle code number -2292.
We can provide a name to this exception and handle it in the exception section as given
below.
DECLARE
Child_rec_exception EXCEPTION;
PRAGMA
EXCEPTION_INIT (Child_rec_exception, -2292);
BEGIN
Delete FROM product where product_id= 104;
EXCEPTION
WHEN Child_rec_exception
THEN Dbms_output.put_line('Child records are present for this product_id.');
END;
/
c) User-defined Exceptions
Apart from sytem exceptions we can explicity define exceptions based on business rules.
These are known as user-defined exceptions.
For Example: Lets consider the product table and order_items table from sql joins to explain
user-defined exception.
Lets create a business rule that if the total no of units of any particular product sold is more
than 20, then it is a huge quantity and a special discount should be provided.
DECLARE
huge_quantity EXCEPTION;
CURSOR product_quantity is
SELECT p.product_name as name, sum(o.total_units) as units
FROM order_tems o, product p
WHERE o.product_id = p.product_id;
quantity order_tems.total_units%type;
up_limit CONSTANT order_tems.total_units%type := 20;
message VARCHAR2(50);
BEGIN
FOR product_rec in product_quantity LOOP
quantity := product_rec.units;
IF quantity > up_limit THEN
message := 'The number of units of product ' || product_rec.name ||
' is more than 20. Special discounts should be provided.
Rest of the records are skipped. '
RAISE huge_quantity;
ELSIF quantity < up_limit THEN
v_message:= 'The number of unit is below the discount limit.';
END IF;
dbms_output.put_line (message);
END LOOP;
EXCEPTION
WHEN huge_quantity THEN
dbms_output.put_line (message);
END;
/