Chap 5
Chap 5
Char Subtypes:
The character subtypes have the same rang of values as their base type.
Character Varchar 2
It has the same syntax as Char. But the difference is, if we assign a character
value to a Char variable and if the length is shorter than the declared length of the
variable PL/SQL blank pads the value to the declared length. The VARCHAR is a subset
of VARCHAR2.
If we assign a character value to a Varchar2 variable, and if the value is shorter
than the declared length of the variable, PL/SQL neither blank pads the neither value nor
strips trailing blanks.
Name1 Char (10);
Name2 Varchar2(10);
If we give name1 and name2 as Frank, name 1 will be stored internally as .Frank.
and name2 as .Frank.. So even though the names are same since the data types are
different they are not same.
Long:-
The variable LONG can store variable-length strings of up to 32760 bytes which
is seven fewer bytes longer than allowed in Varchar2 type variables.
Date:-
The Date data type is to store fixed length data values. It also takes no parameters.
Valid dates include from Jan 1,4712 BC to December 31,4712 AD. When stored in a
database column, date values include to the first day of the current month; the time
portion defaults to midnight.
5.1.4 Variables
Variable are declared in the DECLARE section of the PL/SQL block. Declaration
involves the name of the variable followed by its data type. All statements must end with
a semicolon. Initial values can also be assigned at the time of declaration. Constants are
declared by specifying the key work CONSTANT before the data type.
DECLARE
salary number (6);
When a variable is specified as NOT NULL, you must initialize the variable when it is
declared.
DECLARE
salary number (6);
* “salary” is a variable of datatype number and of length 6.
When a variable is specified as NOT NULL, you must initialize the variable when
it is declared.
For example: The below example declares two variables, one of which is a not null.
DECLARE
salary number(4);
dept varchar2(10) NOT NULL := “HR Dept”;
The value of a variable can change in the execution or exception section of the PL/SQL
Block. We can assign values to variables in the two ways given below.
2) We can assign values to variables directly from the database columns by using a
SELECT.. INTO statement.
Example: The below program will get the salary of an employee with id '1116' and
display it on the screen.
DECLARE
var_salary number(6);
var_emp_id number(6) = 1116;
BEGIN
SELECT salary
INTO var_salary
FROM employee
WHERE emp_id = var_emp_id;
dbms_output.put_line(var_salary);
dbms_output.put_line('The employee '
|| var_emp_id || ' has salary ' || var_salary);
END;
PL/SQL allows the nesting of Blocks within Blocks i.e, the Execution section of an
outer block can contain inner blocks. Therefore, a variable which is accessible to an outer
Block is also accessible to all nested inner Blocks. The variables declared in the inner
blocks are not accessible to outer blocks. Based on their declaration we can classify
variables into two types.
Local variables - These are declared in a inner block and cannot be referenced by
outside Blocks.
Global variables - These are declared in a outer block and can be referenced by its
itself and by its inner blocks.
For Example: In the below example we are creating two variables in the outer block
and assigning thier product to the third variable created in the inner block. The variable
'var_mult' is declared in the inner block, so cannot be accessed in the outer block i.e. it
cannot be accessed after line 11. The variables 'var_num1' and 'var_num2' can be
accessed anywhere in the block.
1> DECLARE
2> var_num1 number;
3> var_num2 number;
4> BEGIN
5> var_num1 := 100;
6> var_num2 := 200;
7> DECLARE
8> var_mult number;
9> BEGIN
10> var_mult := var_num1 * var_num2;
11> END;
12> END;
13> /
5.1.5 Constants
As the name implies a constant is a value used in a PL/SQL Block that remains
unchanged throughout the program. A constant is a user-defined literal value. You can
declare a constant and use it instead of actual value.
For example: If you want to write a program which will increase the salary of the
employees by 25%, you can declare a constant and use it throughout the program. Next
time when you want to increase the salary again you can change the value of the constant
which will be easier than changing the actual value throughout the program.
DECLARE
salary_increase CONSTANT number (3) := 10;
You must assign a value to a constant at the time you declare it. If you do not
assign a value to a constant while declaring it and try to assign a value in the execution
section, you will get a error. If you execute the below Pl/SQL block you will get error.
DECLARE
salary_increase CONSTANT number(3);
BEGIN
salary_increase := 100;
dbms_output.put_line (salary_increase);
END;
DECLARE
-- constant declaration
pi constant number := 3.141592654;
-- other declarations
radius number(5,2);
dia number(5,2);
circumference number(7, 2);
area number (10, 2);
BEGIN
-- processing
radius := 9.5;
dia := radius * 2;
circumference := 2.0 * pi * radius;
area := pi * radius * radius;
-- output
dbms_output.put_line('Radius: ' || radius);
dbms_output.put_line('Diameter: ' || dia);
dbms_output.put_line('Circumference: ' || circumference);
dbms_output.put_line('Area: ' || area);
END;
/
Radius: 9.5
Diameter: 19
Circumference: 59.69
Area: 283.53
IF..ELSE Statement
IF <condition> THEN
<statements>;
ELSE
<statements>;
END IF;
NESTED IF STATEMENT
Nested IF statement have a IF..ELSE part:
IF <condition-1> THEN
<statements>;
ELSE
IF <condition-2> THEN
<statements>;
ELSE
<statements>;
END IF;
END IF;
SQL>declare
2 length number(3):=10;
3 breadth number(3):=12;
4 area number(5);
5 begin
6 if length>=0 then
7 if breadth <=0 then
8 dbms_output.put_line(.Breadth cant be less than 0.);
9 else
10 area:=.5 * length * breadth;
11 dbms_output.put_line(.Breadth cant be less than 0.);
12 end if;
13 else
14 dbms_output.put_line(.Length cant be less than 0.);
15 end if;
16 end;
17/
Area is 60
PL/SQL procedure successfully completed.
Loop statements lets you use the iterative type of control. There are three forms of
LOOP statements. LOOP, WHILE-LOOP and FOR-LOOP.
Loop
The simplest form is the infinite LOOP, WHICH encloses sequence of statements
between the key words LOOP and END LOOP.
LOOP
Sequence of statements;
END LOOP;
Exit
The EXIT statement is used to complete the loop. You can place one or more
EXIT statement inside a LOOP. The EXIT-WHEN statement allows a loop to complete
conditionally when the condition in theWHEN clause is evaluated.
Loop
If..then
Exit; - Exit Loop
End If;
End Loop;
Loop
Fetch C1 Into .
ExitWhen C1% Notfound.
End Loop;
Example
SQL>declare
2 counter binary_integer:=1;
3 begin
4 loop
5 dbms_output.put_line(.Counter values is. || counter);
6 demb_output.put_line( .);
7 counter:=counter+1;
8 exit when counter>5;
9 end loop;
10 end;
/
Counter values is 1
Counter values is 2
Counter values is 2
Counter values is 3
Counter values is 5
PL/SQL procedure successfully completed.
Loop Labels
Like PL/SQL blocks LOOPS can be labeled. The label, an undeclared identifier
enclsed by double angle brackets, must appear at the beginning of the LOOP statement as
follows:
Loop
....
End Loop Label_Name;
<<Outer Block>>
DECLARE
i number(1);
j number(1);
BEGIN
<< outer_loop >>
FOR i IN 1..3 LOOP
<< inner_loop >>
FOR j IN 1..3 LOOP
dbms_output.put_line('i is: '|| i || ' and j is: ' || j);
END loop inner_loop;
END loop outer_loop;
END;
/
While-loop
The WHILE-LOOP statement associates a condition with a sequence of statement
enclosed by the keywords LOOP and END LOOP. Before each iteration of the LOOP,
the condition is evaluated. If the condition evaluates to TRUE the sequence of statements
are evaluated else the loop is by pass.
While Condition Loop
Sequence Of Statements:
End loop;
Consider the following example. This block uses a simple WHILE loop to insert 5
rows into a table. The values of a counter variable, and either of two character strings are
inserted. Which string is inserted depends on the value of the loop index.
For-loop
The number of iterations through a WHILE-LOOP is unknown. The number of
iterates through a FOR-LOOP is known before it enters the LOOP, FOR-LOOP iterates
over a specified range of integers.
Loop
Insert Into Temp (Coll.message) Values (Count, .Ever Green.):
Insert Ten Times Is Ever Green Into Temp End Loop.
GOTO Statement
The GOTO statement branches to a label unconditionally. The label must be
unique within its scope and must precede an executable statement or a PL/SQL block.
When executed, the GOTO statement transfers control to the labeled statement or block.
In the following example, you go to an executable statement farther down in a sequence
of statements:
BEGIN
...
GOTO insert_row;
...
<<insert_row>>
INSERT INTO emp VALUES ...
END;
In the next example, you go to a PL/SQL block farther up in a sequence of
statements:
BEGIN
...
<<update_row>>
BEGIN
UPDATE emp SET ...
...
END;
...
GOTO update_row;
...
END;
The label end_loop in the following example is illegal because it does not precede an
executable statement:
DECLARE
done BOOLEAN;
BEGIN
...
FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<<end_loop>> -- illegal
END LOOP; -- not an executable statement
END;
To debug the last example, just add the NULL statement, as follows:
FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<<end_loop>>
NULL; -- an executable statement
END LOOP;
As the following example shows, a GOTO statement can branch to an enclosing
block from the current block:
DECLARE
my_ename CHAR(10);
BEGIN
<<get_name>>
SELECT ename INTO my_ename FROM emp WHERE ...
BEGIN
...
GOTO get_name; -- branch to enclosing block
END;
END;
NULL Statement
The NULL statement explicitly specifies inaction; it does nothing other than pass
control to the next statement. It can, however, improve readability. In a construct
allowing alternative actions, the NULL statement serves as a placeholder. It tells readers
that the associated alternative has not been overlooked, but that indeed no action is
necessary. In the following example, the NULL statement shows that no action is taken
for unnamed exceptions:
EXCEPTION
WHEN ZERO_DIVIDE THEN
ROLLBACK;
WHEN VALUE_ERROR THEN
INSERT INTO errors VALUES ...
COMMIT;
WHEN OTHERS THEN
NULL;
END;
Types of Cursors
Implicit Cursor
In order to better understand the capabilities of an explicit cursor, you first need to
run through the process of an implicit cursor. The process is as follows:
Any given PL/SQL block issues an implicit cursor whenever an SQL statement is
executed, as long as an explicit cursors 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.
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:
SET SERVEROUTPUT ON
BEGIN
UPDATE student
SET first_name = 'B'
WHERE first_name LIKE 'B%';
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT);
END;
FOR EXAMPLE
Unlike implicit cursor, explicit cursor is defined by the program for any query that
returns more than one row of data. So you need to process an explicit cursor as follows.
First you declare a cursor. Next, you open earlier declared cursor. Next, you fetch earlier
declared and opened cursor. Finally, you close the cursor.
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 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:
The naming conventions that are used in the Oracle Interactive Series advise you
always to name a cursor as c_cursorname. By using a c_ in the beginning of the name, it
will always be clear to you that the name is referencing a cursor.
This is a PL/SQL fragment that demonstrates the first step of declaring a cursor.
A cursor named C_MyCursor is declared as a select statement of all the rows in the
zipcode table that have the item state equal to 'NY'.
DECLARE
CURSOR C_MyCursor IS
SELECT *
FROM zipcode
WHERE state = 'NY';
...
<code would continue here with Opening, Fetching and closing of the cursor>
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.
Record Types
A table-based record is one whose structure is drawn from the list of columns in
the table. A cursor-based record is one whose structure matches the elements of a
predefined cursor. To create a table-based or cursor-based record, use the %ROWTYPE
attribute.
FOR EXAMPLE
-- ch09_1a.sql
SET SERVEROUTPUT ON
DECLARE
vr_student student%ROWTYPE;
BEGIN
SELECT *
INTO vr_student
FROM student
WHERE student_id = 156;
DBMS_OUTPUT.PUT_LINE (vr_student.first_name||' '
||vr_student.last_name||' has an ID of 156');
EXCEPTION
WHEN no_data_found
THEN
RAISE_APPLICATION_ERROR(-2001,'The Student '||
'is not in the database');
END;
The variable vr_student is a record type of the existing database table student.
That is, it has the same components as a row in the student table. A cursor-based record is
much the same, except that it is drawn from the select list of an explicitly declared
cursors. When referencing elements of the record, you use the same syntax that you use
with tables.
record_name.item_name
In order to define a variable that is based on a cursor record, the cursor must first
be declared. In the following lab, you will start by declaring a cursor and then proceed
with the process of opening the cursor, fetching from the cursor, and finally closing the
cursor.
FOR EXAMPLE
DECLARE
vr_zip ZIPCODE%ROWTYPE;
vr_instructor INSTRUCTOR%ROWTYPE;
Record vr_zip has structure similar to a row of the ZIPCODE table. Its elements
are CITY, STATE, and ZIP. It is important to note that if CITY column of the ZIPCODE
table has been defined as VARCHAR2(15), the attribute CITY of the vr_zip record will
have the same datatype structure. Similarly, record vr_instructor is based on the row
of the INSTRUCTOR table.
Opening a Cursor
The next step in controlling an explicit cursor is to open it. When the Open cursor
statement is processed, the following four actions will take place automatically:
1. The variables (including bind variables) in the WHERE clause are examined.
2. Based on the values of the variables, the active set is determined and the PL/SQL
engine executes the query for that cursor. Variables are examined at cursor open
time only.
3. The PL/SQL engine identifies the active set of data—the rows from all involved
tables that meet the WHERE clause criteria.
4. The active set pointer is set to the first row.
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:
or
1. The fetch command is used to retrieve one row at a time from the active set. This
is generally done inside a loop. The values of each row in the active set can then
be stored into the corresponding variables or PL/SQL record one at a time,
performing operations on each one successively.
2. After each FETCH, the active set pointer is moved forward to the next row. Thus,
each fetch will return successive rows of the active set, until the entire set is
returned. The last FETCH will not assign values to the output variables; they will
still contain their prior values.
FOR EXAMPLE
-- ch09_2a.sql
SET SERVEROUTPUT ON
DECLARE
CURSOR c_zip IS
SELECT *
FROM zipcode;
vr_zip c_zip%ROWTYPE;
BEGIN
OPEN c_zip;
LOOP
FETCH c_zip INTO vr_zip;
EXIT WHEN c_zip%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(vr_zip.zip||
' '||vr_zip.city||' '||vr_zip.state);
END LOOP;
END;
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. The syntax for closing the cursor
is
CLOSE cursor_name;
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.
FOR EXAMPLE
Parameterized Cursors.
5.5 Procedures
In this exercise, you will run a script that creates a procedure. Using a text editor
such as Notepad, create a file with the following script.
5.6 Functions
Functions are another type of stored code and are very similar to procedures. The
significant difference is that a function is a PL/SQL block that returns a single value.
Functions can accept one, many, or no parameters, but a function must have a return
clause in the executable section of the function.
The data type of the return value must be declared in the header of the function. A
function is not a stand-alone executable in the way that a procedure is: It must be used in
some context. You can think of it as a sentence fragment. A function has output that
needs to be assigned to a variable, or it can be used in a SELECT statement.
Syntax:
The function does not necessarily have any parameters, but it must have a
RETURN value declared in the header, and it must return values for all the varying
possible execution streams. The RETURN statement does not have to appear as the last
line of the main execution section, and there may be more than one RETURN statement
(there should be a RETURN statement for each exception). A function may have IN,
OUT, or IN OUT parameters, but you rarely see anything except IN parameters since it is
bad programming practice to do otherwise.
Executing:
Quantity_On_Hand<Reorder_Level
A trigger action is the procedure that contains the SQL statements and PL/SQL
code to be executed when a triggering statement is issued and the trigger restriction
evaluates to true.
Some important points to note:
You can create only BEFORE and AFTER triggers for tables. (INSTEAD OF
triggers are only available for views; typically they are used to implement view updates.)
You may specify up to three triggering events using the keyword OR. Furthermore,
UPDATE can be optionally followed by the keyword OF a list of attribute(s) in
<table_name>. If present, the OF clause defines the event to be only an update of the
attribute(s) listed after OF. Here are some examples:
. INSERT ON R.
. INSERT OR DELETE OR UPDATE ON R .
.UPDATE OF A,B OR INSERT ON R.
If FOR EACH ROW option is specified, the trigger is row-level; otherwise, the
trigger is statement-level.
For a row-level trigger, a trigger restriction can be specified in the WHEN clause,
enclosed by parentheses. The trigger restriction is a SQL condition that must be satisfied
in order for ORACLE to fire the trigger. This condition cannot contain subqueries.
Without the WHEN clause, a trigger is fired by every triggering event.
<trigger_body> is a PL/SQL block, rather than sequence of SQL statements. Oracle
has placed certain restrictions on what you do in <trigger_body>, in order to avoid
situations where one trigger performs an action that triggers a second trigger, which then
triggers a third, and so on, which could potentially create an infinite loop.
The restrictions on <trigger_body> include:
You cannot modify the same relation whose modifiction is the event triggering
the trigger.
You cannot modify a relation connected to the triggering relation by another
constraint such as a foreign-key constraint.
Types of Triggers
TRIGGER TIMING
BEFORE triggers execute the trigger action before the triggering statement.
AFTER
Triggers execute the action after the triggering statement is executed. So with these
Combinations we can create four types as follows:
BEFORE statement trigger
BEFORE row trigger
AFTER statement trigger
After row trigger
<BEFORE,AFTER>
DECLARE
<variable> declaration;
<constant> declaration;
BEGIN
<PL/SQL subprogram body>
EXCEPTION
<PL/SQL Exception block>
END;
/
CREATE or REPLACE TRIGGER trigger name: Creates a trigger with the given
name otherwise overwrites an existing trigger with the same name.
{BEFORE , AFTER }: Indicates the where should trigger get fired. BEFORE
trigger execute before when statement execute before time or AFTER trigger
execute after when statement execute after time.
{INSERT, UPDATE and DELETE}: Determines the performing trigger event.
More than one triggering events allow can be used together separated by OR
keyword.
ON Table Name: Determine the perform trigger event in selected Table.
[Referencing {old AS old, new AS new}]: Reference the old and new values of
the data being changed. :old use to existing row perform and :new use to execute
new row to perform. The reference names can also be changed from old (or new)
to any other user-defined name. You cannot reference old values when inserting a
record, or new values when deleting a record, because they do not exist.
for each row: Trigger must fire when each row gets Affected (Row Level Trigger)
or just once when the entire sql statement is executed(statement level Trigger).
WHEN (condition): Valid only for row level triggers. The trigger is fired only for
rows that satisfy the condition specified.
Deleting trigger:
To delete a trigger we use DROP TRIGGER command.
Syntax:
DROP TRIGGER trigger_name;
Example:
DROP TRIGGER trg1;
Locks
Lock is a system object associated with a shared resource such as a data item of
an elementary type, a row in a database, or a page of memory. In a database, a lock on a
database object (a data-access lock) may need to be acquired by a transaction before
accessing the object. Correct use of locks prevents undesired, incorrect or inconsistent
operations on shared resources by other concurrent transactions.
When a database object with an existing lock acquired by one transaction needs to
be accessed by another transaction, the existing lock for the object and the type of the
intended access are checked by the system. If the existing lock type does not allow this
specific attempted concurrent access type, the transaction attempting access is blocked
(according to a predefined agreement/scheme).
In practice a lock on an object does not directly block a transaction's operation
upon the object, but rather blocks that transaction from acquiring another lock on the
same object, needed to be held/owned by the transaction before performing this
operation. Thus, with a locking mechanism, needed operation blocking is controlled by a
proper lock blocking scheme, which indicates which lock type blocks which lock type.
The common interactions between these lock types are defined by blocking behavior as
follows:
An existing write-lock on a database object blocks an intended write upon the same
object (already requested/issued) by another transaction by blocking a
respective write-lock from being acquired by the other transaction. The second write-
lock will be acquired and the requested write of the object will take place
(materialize) after the existing write-lock is released.
A write-lock blocks an intended (already requested/issued) read by another
transaction by blocking the respective read-lock .
A read-lock blocks an intended write by another transaction by blocking the
respective write-lock .
A read-lock does not block an intended read by another transaction. The
respective read-lock for the intended read is acquired (shared with the previous read)
immediately after the intended read is requested, and then the intended read itself
takes place.
Optimistic
Pessimistic
Pessimistic locking assumes that concurrent transactions will conflict with each
other, and requires resources to be locked after they are read and only unlocked after the
application has finished using the data.
Implicit Locking
Objectivity/DB will implicitly obtain the appropriate locks for your application at
the point at which they are needed. An operation that reads an object will obtain a read
lock; an operation that modifies an object will obtain a write lock.
Explicit Locking
Implicit locking obtains access rights to resources as they are needed by an
application. In general, the automatic locking by Objectivity/DB provides a level of
federated database concurrency that is sufficient for most applications.
Some applications, however, may need to reserve access to all required resources
in advance. Reasons for doing so might be to secure required access rights to the
necessary objects before beginning an operation, or to prevent other sessions from
modifying objects critical to the operation.
5.9 Summary:
Cursor is the work area which oracle reserves for internal processing of SQL
statements. This work is private for oracles reserved are called cursor. Oracle uses
implicit cursor for its internal processing. Even if we execute a SELECT statement oracle
reserve a private SQL area in memory called cursor.
1. Write a PL/SQL program to print even and odd numbers from given range
(Accept Number range from user). (Sum-2010)
2. Explain implicit and explicit cursors. (Sum-2010)
3. What is database trigger? Compare database triggers and procedures and explain
use of database trigger. (Sum-2010)
4. What is cursor? Explain the types of cursors. (Win -2010)
5. Describe Event Condition Action (ECA) model of triggers. (Win -2010)
6. How to use function in PL/SQL? Explain with two examples. (Win -2010)
7. What is cursor? Explain steps for using explicit cursor. (Sum-2011)
8. Write a PL/SQL program to print numbers from 50 to 60 using for loop. (Sum-11)
9. Give any 4 advantages of using PL/SQL. (Sum-2011)
10. What is cursor? Explain the types of cursors. (Win -2011)
11. How to use function in PL/SQL? Explain with two examples. (Win -2011)
12. Explain in brief concept of trigger. (Win -2012)
13. Explain block structure of PL/SQL (Win -2012)
14. List out any four statements of PL/SQL. (Win -2012)
15. Describe in brief control structure of PL/SQL. (Win -2012)
16. With suitable example list and explain types of cursors. (Sum-2013)
17. Draw and explain in brief PL/SQL block structure. (Sum-2013)