Sunteți pe pagina 1din 181

PL/SQL

Database Languages
Procedural Language & Non-Procedural Language
 In a procedural language  Non-procedural
each step of the task (i.e. Programming languages allow
procedure ) is defined users and professional
precisely . programmers to specify the
 Procedural languages are results they want without
used in the traditional specifying how to solve the
programming that is based problem.
on algorithms or a logical  Ex. SQL (Structured Query
step-by-step process for Language) used for RDBMS.
solving a problem.  Non-procedural language is
 Examples: C,C++, Java. concerned with the
 WHAT & HOW a process  WHAT not the HOW.
should be done !!
SQL
 Though SQL is the natural language of the
DBA it suffers from various inherent
disadvantages, as compared to conventional
Prog.Languages.
It does not have procedural capabilities such
as looping, conditional checking, branching.
Business functions for change and retrieval that should operate upon its instance,
to be specified in a declarative fashion.
Typically, they are implemented outside of the database and they allow the
developer to choose the persistence mechanism; usually, the Oracle Database is
just one possibility among several.
Why Use PL/SQL?

• PL/SQL is Oracle's procedural language extension to SQL.


– PL/SQL allows you to mix SQL statements with procedural
constructs.
• This approach is generally called the thick database paradigm,
because
– PL/SQL subprograms inside the database issue the SQL statements
from code that implements the surrounding business logic; and
– because the data can be changed and viewed only through a PL/SQL
interface.
What is so great about PL/SQL anyway?

• PL/SQL is a procedural extension of SQL


• making it extremely simple to write procedural code that includes SQL as
if it were a single language.
• The data types in PL/SQL are a super-set of those in the database, so you
rarely need to perform data type conversions when using PL/SQL.
• Average Java or .NET programmer how they find handling date values
coming from a database. They can only wish for the simplicity of PL/SQL.
• When coding business logic in middle tier applications, a single business
transaction may be made up of multiple interactions between the
application server and the database.
• This adds a significant overhead associated with network traffic.
• In comparison, building all the business logic as PL/SQL in the database
means client code needs only a single database call per transaction,
reducing the network overhead significantly.
Advantages of PL/SQL
• These are the Advantages of PL/SQL
• Block Structures: PL SQL consists of blocks of code, which can be
nested within each other. Each block forms a unit of a task or a
logical module. PL/SQL Blocks can be stored in the database and
reused.
• Procedural Language Capability: PL SQL consists of procedural
language constructs such as conditional statements (if else
statements) and loops like (FOR loops).
• Better Performance: PL SQL engine processes multiple SQL
statements simultaneously as a single block, thereby reducing
network traffic.
• Error Handling: PL/SQL handles errors or exceptions effectively
during the execution of a PL/SQL program. Once an exception is
caught, specific actions can be taken depending upon the type of the
exception or it can be displayed to the user with a message.
Access schema where the red
dots s1, s2, and so on represent
the synonyms that denote the
subset of units in the Code
schema that make up the
The inner white circle
exposed interface he only represents the Data schema.
database calls that are
allowed invoke the interface
subprograms.

every single select, insert, update, delete,


merge, commit, and rollback that executes
when the application is in ordinary use is The surrounding gray
issued from one of the PL/SQL units in ring represents
this schema the Code schema.
• There are only two such languages that can run
inside an Oracle Database: Java and PL/SQL.
But Java has only subroutine support for SQL.
• The DBMS_Sql package is PL/SQL’s
subroutine interface for doing SQL; but it also,
uniquely, has language features for doing SQL.
Dynamic SQL
SQL is internal host language of RDBMS so it is
closer to data and thus faster in operations.
When a commercial application is created ,its spec
knows exactly what to do ,simply because such
programmer created code spec is written to do a
specific job,
• For example a pl/sql program can prompt
– An account number
– An account to be withdrawn
– Then update record data in both the account and
Transaction tables
CONT…
PL/SQL is an imperative 3GL that was designed
specifically for the seamless processing of SQL
commands.
It provides specific syntax for this purpose and
supports exactly the same datatypes as SQL.
Server-side PL/SQL is stored and compiled in
Oracle Database and runs within the Oracle
executable.
 It automatically inherits the robustness,
security, and portability of Oracle Database.
PL/SQL
• PL/SQL is a combination of SQL along with the
procedural features of programming languages.
• It was developed by Oracle Corporation in the early
90’s to enhance the capabilities of SQL.

The PL/SQL Engine:

Oracle uses a PL/SQL engine to processes the
PL/SQL statements.
• A PL/SQL language code can be stored in the client
system (client-side) or in the database (server-side).
The PL/SQL code block knows
• Tables on which SQL queries will be fired:
– Data type of each column.
– Constraints defined for each table and column
– Which coulmns must be updated.
SQL statement that change from a specific runtime execution
to another are called dynamic SQL statement.
Dynamic SQL is an enhanced form of SQL , Dynamic SQL
permits the constructing of SQL statement dynamically and
is useful when writing code spec that must adjust to
varying databases, conditions on servers.
When to consider using dynamic SQL
• Dynamic SQL should be considered,if any of
the following blocks of information are
unknown at the time when the code spec is
being created:
– The text of the SQL statement
– The number of columns
– The data types of columns
– References to database objects such as
columns,indexes, sequences,tables,usersnamess
and views
A Simple PL/SQL Block:
• Each PL/SQL program consists of SQL and
PL/SQL statements which from a PL/SQL
block.
• PL/SQL Block consists of three sections:
• The Declaration section (optional).
• The Execution section (mandatory).
• The Exception Handling (or Error) section
(optional).
Dynamic SQL Using
• Understanding PL/SQL Block Structure
Declaration Section:
• The Declaration section of a PL/SQL Block starts
with the reserved keyword DECLARE.
• This section is optional and is used to declare any
placeholders like variables, constants, records
and cursors, which are used to manipulate data in
the execution section.
• Placeholders may be any of Variables, Constants
and Records, which stores data temporarily.
Cursors are also declared.
Declare
• our program stores values in variables and
constants.
• As the program executes, the values of variables
can change, but the values of constants cannot.
• You can declare variables and constants in the
declarative part of any PL/SQL block,
subprogram, or package.
• Declarations allocate storage space for a value,
specify its datatype, and name the storage
location so that you can reference it.
Some examples follow:
DECLARE
birthday DATE;
emp_count SMALLINT := 0;
The first declaration names a variable of type
DATE.
The second declaration names a variable of type
SMALLINT and uses the assignment operator to
assign an initial value of zero to the variable.
The next examples show that the expression
following the assignment operator can be
arbitrarily complex and can refer to previously
DECLARE initialized variables:
pi REAL := 3.14159; radius REAL := 1; area REAL := pi *
radius**2;
Execution Section:
• The Execution section of a PL/SQL
Block starts with the reserved keyword
BEGIN and ends with END.
• This is a mandatory section and is the
section where the program logic is
written to perform any task.
• The programmatic constructs like
loops, conditional statement and SQL
statements form the part of execution
section.
Exception Section:

• The Exception section of a PL/SQL Block starts with the


reserved keyword EXCEPTION.
• This section is optional. Any errors in the program can
be handled in this section, so that the PL/SQL Blocks
terminates gracefully. If the PL/SQL Block contains
exceptions that cannot be handled, the Block
terminates abruptly with errors.

Every statement in the above three sections must end


with a semicolon ; . PL/SQL blocks can be nested
Write PL/SQL Block Which Will Display Reverse Number Of
Given Number.

• SQL> DECLARE
• 2 no integer;
• 3 rev integer:=0;
• 4 BEGIN
• 5 no:=&'Enter_No.';
• 6 WHILE (no>0) LOOP
• 7 rev:=rev*10+MOD(no,10);
• 8 no:=TRUNC(no/10);
• 9 END LOOP;
• 10 DBMS_OUTPUT.PUT_LINE('Reverse No. Is'||' : '||rev);
• 11 END;
• 12 /
• Enter value for enter_no: 123456
• old 5: no:='&Enter_No.';
• new 5: no:='123456';
• Reverse No. Is : 654321
Write PL/SQL Block To Display Factorial Of Given
Number.

• DECLARE
• num NUMBER:='&Input_Number';
• i NUMBER;
• f NUMBER:=1;
• BEGIN
• FOR i IN 1..num LOOP
• f := f * i;
• END LOOP;
• DBMS_OUTPUT.PUT_LINE(f||' Is Factorial Of '||num);
• END;
• /
• Enter value for input_number: 5

• 120 Is Factorial Of 5

Write a Pl/SQL code block that will accept an account number from user and debit an
amount of Rs 2000 from the account has a minimum balance of 500 after the amount is
debited .The process is to be fired on the account table.
Declare
• Acct_balance number(11,2);
• Acct_no varchar2(6);
• Debit_amt number(5):=2000
• Min_bal constant number(5,2):=500.00
Begin
/* Accept an account _no from user*/
Acct_no:=&acct_no;
/* retreiving bal.from account table where account_no in the table is equal to the account_no enetered
by the user*/
SELECT bal INTO acct_balance
FROM accounts
WHERE account_id=acct_no;
/*substract if the balance is greater than equal to the min bal. of Rs 500 .If the condition is satisfied an
amount of Rs 2000 is subtracted from the balance of the corresponding account no.*/
IF acct_balance >+MIN_BAL THEN
UPDATE account SET bal=bal-debit_amt
WHERE account_id=acct_no;
ENDIF;
END
Displaying user msg on the screen
• Message can be displayed on screen:
• -DBMS_OUTPUT:-is a package that includes a number of
procedures and functions that information in a buffer so that it
can be retrieved later.These function can also be used to
display messages to the user.
• PUT_LINE:-
• It can be used to disply message to the user Put_line
expects a single parameter of character data type.If
used to display a message .
DIFFERENCE BETWEEN PL/SQL AND
SQL
• When a SQL statement is issued on the client computer,
the request is made to the database on the server, and the
result set is sent back to the client.
• As a result, a single SQL statement causes two trips on the
network.
• If multiple SELECT statements are issued, the network
traffic increase significantly very fast.
• For example, four SELECT statements cause eight network
trips.
• If these statements are part of the PL/SQL block, they are
sent to the server as a single unit.
• The SQL statements in this PL/SQL program are executed
at the server and the result set is sent back as a single unit.
There is still only one network trip made as is in case of a
single SELECT statement.
Example
• Write a PL/SQL code block to calculate the area of
a circle for a value of radius varying From 3 to
7,store the radius and the corresponding values of
calculated area in an empty table named Areas,
consisting of two columns Radius and Area.

RADIUS AREA
Radius AREA
3 28.26
4 50.24
5 78.5
6 113.04
7 153.86
OUTPUT

RADIUS AREA
3 28.26
4 50.24
5 78.5
6 113.04
7 153.86
Create table AREAS (RADIUS NUMBER(5),AREA NUMBER
(14,2));
DECLARE
Pi constant number (4,2):=3.14;
Radius number (5);
Area number (14,2);
BEGIN
Radius :=3;
WHILE RADIUS <= 7
LOOP
Area := pi* power (radius ,2);
INSERT INTO areas VALUES (radius,area)
Radius := radius + 1
END LOOP;
END;
OUTPUT

RADIUS AREA
3 28.26
4 50.24
5 78.5
6 113.04
7 153.86
This is an iteration condition. Enter a number from Key board. If
it is not zero print 'natural number', else print 'enter wrong
number'

Declare
NUM number:=&N;
begin
if(NUM>0)
dbms_output.put_line (NUM||'Natural Number');
else
dbms_output.put_line (NUM||'Wrong Number');
exit when NUM1=100;
end if;
end;
Print Hello World in Pl/Sql
• Begin
• dbms_output.put_line ('Hello World');
• end;
Assignment
• Write a pl/sql block of code for inverting a
number 5639 to 9365
Example
• Write a pl/sql block of code to achieve he
following .
• If there are no transaction taken place in the
last 365 days then mark the account status as
inactive ,and then record the account number,
the opening date and the type of account in the
INACTIVE_ACCT_MSTR table.
ACCT_NO OPNDT TYPE
CREATE TABLE INACTV_ACCT_MSTR
SYNTAX:
• DECLARE
• mACCT_NO VARCHAR2(10);
• mANS varchar 2(3);
• mOPNDT date;
• mTYPE varchar2(2);
• BEGIN
• mACCT_NO VARCHAR2(10);
• mANS VARCHAR(2);
• mOPNDT date;
• mTYPE VARCHAR2(2);
• BEGIN
• mACCT_NO :=mOPNDT_NO;
SELECT ’YES’INTO mANS
FROM TRANS_MSTR
WHERE ACCT__NO = mACCT_NO=mACCT_NO
Groupby ACCT_NO HAVING MAX (SYSDATE-DT)>365;
IF mANS=‘yes’THEN
GOTO mark_status;
ELSE
Dbms_output.put_line (‘Account number’||mACCT_NO||’is active’);
ENDIF
<<MARK_STATUS>>
UPDATE ACCT_MSTR SET STATUS = ‘’I’’ WHERE ACCT_NO = mACCT_NO;
SELECT OPNDT,TYPE INTO Mopndt,mTYPE
FROM ACCT_MSTR WHERE ACCT_NO =Macct_NO;
INSERT INTO INACTV_ACCT_MSTR (ACCT_NO,OPNDT,TYPE)
VALUES (MACCT_NO,mOPNDT,mTYPE);
Dbms_output.put_line(‘Account number ’:’||mACCT_NO | | ‘ is marked as inctive’);
END;
Transactions
• Transaction is group of event that occurs between any of the
following
– Connecting to Oracle
– Disconnecting from Oracle
– Committing changes to the datanase table
– Rollback
 Commit:- Transaction can be closed either a commit or rollback.
with this data can be changed or all changes made to
the table data are undone.
 Commit ends the transaction and makes permanent any changes made
during transactions. Syntax-Commit;
 Rollback:- It does exactly opposite of Commit.It ends the trnsaction but
undoes any changes made during the transaction
 Savepoint:- Is optional and is used to rollback a partial transaction
.When it is used with ROLLBACK part of a transaction can be undone .
• Write a Pl/SQL block of code that first inserts a
record in’Emp table’.
– Update the salaries of Blake and Clarke by Rs 2000 &Rs
1500.
– Then check to see that the total salary dos not exceed
20000.
– If the total salary is greater than 20000 then undo the
updates made to the salaries of Blake & Clarke.
DECLARE
Total_sal number((9);
BEGIN
INSERT INTO emp values (‘E005’.’John’,1000);
/*Defining a savepoint */
SAVEPOINT no_updates;
/*updation of the salaries of Blake and Clarke in the ‘Emp table’*/
UPDATE emp SET sal=sal+2000
where emp_name=‘Blake;’;
UPDATE emp SET sal =sal + 1500
Where emp_name =‘clark’
• SELECT sum(sal)INTO total_sal
FROM emp;
IF total_sal > 20000 THEN
ROLLBACK To Savepoint no_update;
ENDIF;
COMMIT;
END:
Transactions
• Write a PL/SQL block of code that first withdraws an amount
of Rs 1,000.
• Then deposits an amount of Rs 1,40,000.Update the current
balance.
• Then check to see that the current balance of all the accounts
in the bank does not exceed Rs 2,00,000.
• If the balance exceeds Rs 2,00,000 then undo the deposit just
made.
DECLARE
mBal number(8,2);
BEGIN
INSERT INTO TRANS_MSTR
(TRANS_NO,ACCT_NO,DT,TYPE,PARTICULAR,DR_CR,AMT,BALANCE)VAL
UES( ‘T100’,’’CA10’,’04-JUL-2004’,’C’,’Telephone Bill’,’W’,1000,31000);
UPDATING THE BAL OF ACCT NO CA10 ACCT TABLE
UPDATE ACCT_MSTR SET CURBAL=CURBAL-1000 WHERE ACCT_NO
=‘CA10’;
SAVEPOINT no_update ;
INSERT INTO TRANS_MSTR
(
TRANS_NO,ACCT_NO,DT,TYPE,PARTICULAR,DR_CR,AMT,BALANCE)V
ALUES(‘T101’,’CA10’,’04-JUL-2004’,’C’,’DEPOSIT’,’D’,14000,171000);
/*Updating ACCT_MSTR SET CURBAL = CURBAL-1000 WHERE ACCT_NO
=‘CA10’ in the ACCT_MSTR’TABLE*/
Savepoint no_update;
SAVEPOINT no_update ;
/*Insertion of a record in the ‘TRANS_MSTR’ table for
deposits */.
INSERT INTO TRANS_MSTR
(
TRANS_NO,ACCT_NO,DT,TYPE,PARTICULAR,DR_C
R,AMT,BALANCE)VALUES(‘T101’,’CA10’,’04-JUL-
2004’,’C’,’DEPOSIT’,’D’,14000,171000);
/*Updating ACCT_MSTR SET CURBAL = CURBAL-1000
WHERE ACCT_NO =‘CA10’ in the ACCT_MSTR’TABLE*/

Defining a saving point.*/

Savepoint no_update;
UPDATE ACCT_MSTR SET CURBAL = CURBAL +140000 WHERE
ACCT_NO=‘CA10’;
‘ACCT_MSTR’TABLE INTO A VARIABLE.*/
SELECT SUM(CURBAL)INTO Mbal FROM ACCT_MSTR;
IF Mbal >200000 THEN
ROLLBACK TO SAVEPOINT no_update;
END If;
/* MAKE THE CHANGES PERMANENT */
COMMIT;
END:
OUTPUT:
PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.
PL/SQL programming
Cursors and Procedures

46
What is CURSOR
A cursor is a set of rows together with a pointer that identifies a
current row.
In other word, Cursor is a database object used by applications to
manipulate data in a set on a row-by-row basis
Cursors is to retrieve data from a result set one row at a time,
instead of the SQL commands that operate on all the rows in the
result set at one time.
We use cursor when we need to update records in a database table
in singleton fashion means row by row.
This is a control structure for successive traversal through data.
The rows in the result set will be processed sequentially by the
application.
Cursor acts as an iterator over a collection of rows in the result
set.
Remember the SELECT INTO……
?
• It only allowed the retrieval of one row
Select attribute into variable from … where …

Or

Select count(*) into variable from ………

But when we want to retrieve multiple rows we


need to use what is called a CURSOR
48
Cont…CURSOR
The oracle engine uses a work area for its
internal processing in order to execute an SQL
Statement.
This work area is private to SQL’s operations
and is called a CURSOR.
Cursors is a database objects to retrieve data
from a result set one row at a time.
We use cursor when we need to update records
in a database table in singleton fashion means
row by row.
Cont….
Cursor is a temporary memory area (context area)
where Oracle executes SQL statements.
Oracle associates every SELECT statement with a
cursor to hold the query information in this context
area.
The Data that is stored in the Cursor is called the
Active Data Set.
Oracle has a predefined area in main memory
Set aside, within that cursors are opened.
Hence size of the cursor are limited by the size of
this pre-defined area.
Cursor Functions
Active set

7369 SMITH CLERK


7566 JONES MANAGER
Cursor 7788 SCOTT ANALYST Current row
7876 ADAMS CLERK
7902 FORD ANALYST

51
Cursor
• When a SQL statement is executed from PL/SQL program unit the Oracle
database server assigns a private work area for that statement and that area
contains processing info of that SQL statement and information about data
returned.
• The PL/SQL cursor is a pointer to this private SQL area - i.e : Using this
cursor we assign name to that private area and we have a handle to control
the information stored.

For example:-

when we execute a select statement in PL/SQL, select statement returns a result-set(a virtual table which
has same structure as table(rows and columns)).
The cursor points to this virtual table and this virtual table is transient(not permanent), it only exist for the
duration of SELECT statement execution
Declaring the Cursor

DECLARE
CURSOR low_pay
IS SELECT surname,salary
FROM Personnel
where salary < 12000;
v_surname personnel.surname%TYPE; (attribute provides
the datatype of a variable or database
column.);
v_salarypersonnel.salary%TYPE;
BEGIN
…..
Because a cursor is associated with multiple rows they are normally
used with LOOP structures

53
%TYPE
• Using the %TYPE Attribute The %TYPE attribute provides
the datatype of a variable or database column.;
• Variables declared using %TYPE are treated like those
declared using a datatype specifier.
• For example, given the previous declarations, PL/SQL treats
debit like a REAL(7,2) variable.
• A %TYPE declaration can also include an initialization
clause.
• The %TYPE attribute is particularly useful when declaring
variables that refer to database columns.
• You can reference a table and column, or you can reference
an owner, table, and column
• you do not need to know the actual datatype, and attributes such as precision,
scale, and length. If the database definition of the column changes, the datatype
of the variable changes accordingly at run time
%TYPE is used to declare a field with the same type as -- that of
a specified table's column:

DECLARE v_EmpName emp.ename%TYPE;


BEGIN
SELECT ename INTO v_EmpName
FROM emp WHERE ROWNUM = 1;
DBMS_OUTPUT.PUT_LINE('Name = ' || v_EmpName);
END; /
-- %ROWTYPE is used to declare a record with the same types
as -- found in the specified database table, view or cursor:
DECLARE v_emp emp%ROWTYPE;
BEGIN v_emp.empno := 10;
v_emp.ename := 'XXXXXXX';
END; /
Cursor Attributes
Obtain status information about a cursor.

Attribute Type Description


%ISOPEN Boolean Evaluates to TRUE if the cursor
is open
%NOTFOUND Boolean Evaluates to TRUE if the most
recent fetch does not return a row
%FOUND Boolean Evaluates to TRUE if the most
recent fetch returns a row;
complement of %NOTFOUND
%ROWCOUNT Number Evaluates to the total number of
rows returned so far

56
DECLARE c_id customers.id%type;
c_name customerS.No.ame%type;
c_addr customers.address%type;
CURSOR c_customers is SELECT id, name, address FROM
customers;
BEGIN OPEN c_customers;
LOOP FETCH c_customers into c_id, c_name, c_addr;
EXIT WHEN c_customers %notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
END LOOP;
CLOSE c_customers;
END; /
1. Ramesh Ahmedabad
2 Khilan Delhi
3 kaushik Kota
4 Chaitali Mumbai
5. Hardik Bhopal
6 Komal MP
TYPES OF CURSORS
Cursor are classified depending on the circumstances
they are opened.
 If the Oracle engine opened a cursor for its internal
processing it is known as an Implicit Cursor.
 An implicit cursor is one created "automatically" for
you by Oracle when you execute a query. It is simpler
to code
 A Cursor can also be opened for processing data
through a PL/SQL block,on demand ,Such a user-
defined cursor is known as an Explicit Cursor.
 Oracle engine creates any implicit or Explicit
Cursor .
Explicit cursor
An explicit cursor is defined in the declaration section of
the PL/SQL Block.
It is created on a SELECT Statement which returns
more than one row.
A suitable name for the cursor.

General Syntax for creating a cursor is as given below:

CURSOR cursor_name IS select_statement;

cursor_name – A suitable name for the cursor.

select_statement – A select query which returns multiple


rows.
How to use Explicit Cursor?

There are four steps in using an Explicit


Cursor.
• DECLARE- the cursor in the declaration section.
• OPEN -the cursor in the Execution Section.
• FETCH- the data from cursor into PL/SQL
variables or records in the Execution Section.
• CLOSE -the cursor in the Execution Section
before you end the PL/SQL Block.
Declare Cursor
• A cursor is declared by defining the SQL statement that
returns a result set.
Open
• A Cursor is opened and populated by executing the SQL
statement defined by the cursor.
Fetch
• When cursor is opened, rows can be fetched from the
cursor one by one or in a block to do data manipulation.
Close
• After data manipulation, we should close the cursor
explicitly.
Deallocate
• Finally, we need to delete the cursor definition and
released all the system resources associated with the
cursor.
Controlling Cursor…
Open the cursor.
Pointer

Cursor
Fetch a row from the cursor.

Pointer
Cursor
Continue until empty.

Pointer

Cursor
Close the cursor.

Cursor
63
Controlling Cursor
No

Yes
DECLARE OPEN FETCH EMPTY? CLOSE

• Create a • Identify • Load the • Test for • Release


named the active current existing the active
SQL area set row into rows set
variables • Return to
FETCH if
rows
found

64
Declaring a Cursor in the Declaration Section:
DECLARE
CURSOR emp _cur IS
SELECT * FROM emp_ tbl WHERE salary > 5000;
Accessing the records in the cursor:
Once the cursor is created in the declaration
section we can access the cursor in the
execution section of the PL/SQL program.
How to access an Explicit Cursor?
• These are the three steps in accessing the cursor.
1) Open the cursor.
2) Fetch the records in the cursor one at a time.
3) Close the cursor.
• General Syntax to open a cursor is:
OPEN cursor_name; General Syntax to fetch
records from a cursor is:
FETCH cursor_name INTO record_name; OR
FETCH cursor_name INTO variable_list;
• When a cursor is opened, the first row becomes
the current row.
• When the data is fetched it is copied to the
record or variables and the logical pointer moves
to the next row and it becomes the current row.
• On every fetch statement, the pointer moves to
the next row.
• If you want to fetch after the last row, the
program will throw an error.
• When there is more than one row in a cursor
• we can use loops along with explicit cursor
attributes to fetch all the records.
Remember while fetching a row:
• We can fetch the rows in a cursor to a PL/SQL
Record or a list of variables created in the PL/SQL
Block.
· If you are fetching a cursor to a PL/SQL Record,
the record should have the same structure as the
cursor.
· If you are fetching a cursor to a list of variables,
the variables should be listed in the same order in
the fetch statement as the columns are present in
the cursor.
• General Form of using an explicit cursor is:
• DECLARE variables;
• records;
• create a cursor;
• BEGIN
• OPEN cursor;
• FETCH cursor;
• process the records;
• CLOSE cursor;
• END;
OPEN,FETCH, CLOSE, %NOTFOUND Block1
A variation using WHILE Loop and %FOUND
DECLARE
CURSOR low_pay FETCH commands
IS SELECT surname,salary FROM
Personnel where salary < DECLARE
30000; CURSOR low_pay
v_surname IS SELECT surname,salary
personnel.surname%TYPE; FROM Personnel where salary < 30000;
v_salary v_surname
personnel.salary%TYPE; personnel.surname%TYPE;
BEGIN v_salary
personnel.salary%TYPE;
OPEN low_pay; BEGIN
LOOP OPEN low_pay;
FETCH low_pay INTO v_surname, FETCH low_pay INTO v_surname,
v_salary; v_salary;
EXIT when WHILE low_pay%FOUND
low_pay%NOTFOUND; LOOP
DBMS_OUTPUT.PUT_LINE(v_surname
DBMS_OUTPUT.PUT_LINE(v_surname ||' '|| v_salary);
||' '|| v_salary); FETCH low_pay INTO v_surname,
v_salary;
END LOOP; END LOOP;
CLOSE low_pay; CLOSE low_pay;
END; END; FETCH commands
ExampleS:
DECLARE
emp_rec emp_tbl%rowtype;
CURSOR emp_cur IS
SELECT * FROM WHERE salary > 100;
BEGIN
OPEN emp_cur;
FETCH emp_cur INTO emp_rec;
dbms_output.put_line (emp_rec.first_name || ' ' ||
emp_rec.last_name);
CLOSE emp_cur;
END;
Four Attributes for IMPLICIT
cursors
Attributes Return values Example

%FOUND TRUE, if fetch statement returns at Cursor_name%FOUND


least one row.
FALSE, if fetch statement doesn’t
return a row.

%NOTFOUND TRUE, , if fetch statement doesn’t Cursor_name%NOTFOUND


return a row.
FALSE, if fetch statement returns at
least one row.
%ROWCOUNT The number of rows fetched Cursor_name%ROWCOUNT
by the fetch statement
If no row is returned, the
PL/SQL statement returns an
error.
%ISOPEN TRUE, if the cursor is already Cursor_name%ISNAME
open in the program
FALSE, if the cursor is not
opened in the program.
Example of SQL %Found
The HRD has decided to raise the salary of employees by 0.15 .write a PL/SQL
block to accept the employee number and update the salary of that employee.
Display appropriate message Based on the existence of the records in the employee
table.
BEGIN
UPDATE employee SET salary * 0.15
WHERE emp_code =& emp_code;
IF SQL%FOUND THEN
dbms_output.put_line(Employee Record Modified Successfully’);
ELSE
dbms_output.put_line(‘Employee No. Does not Exists ’);
ENDIF;
END;
Example of SQL %NOT Found
The HRD manager has decided to raise the salary of employees working as ‘Programmers’
By 0.15.Write a PL/SQL block to accept the employees number and update the salary of that
employeee

BEGIN
UPDATE employee SET salary * 0.15
WHERE emp_code =& emp_code;
IF SQL%NOTFOUND THEN
dbms_output.put_line(‘Employee No. Does not Exists ‘);
ELSE
dbms_output.put_line(‘Employee Record Modified Successfully’);
ENDIF;
END;T
SQL %ROWCOUNT
The HRD has decided to raise the salary of
employees working as ‘programmers’ 0.15 .write
a PL/SQL block to accept the employee number
and update the salary of that employee.
Display appropriate message Based on the
existence of the records in the employee table.
DECLARE
rows_affected char(4);
BEGIN
UPDATE employee SET salary= *0.15
WHERE job=‘programme’;
Rows_affected := to char(sql % rowcount);
IF SQL % ROWCOUNT> 0 THEN
Dbms_output_line(rows_affected||’Employee Records
Modified Successfully’);
ELSE
Dbms_ouput.put_line(‘There are no Employees
working as programmers’);
ENDIF;
END IF;
SQL
• Basic commands
– SELECT, INSERT, DELETE, UPDATE
• Always remember to state the table(s) you
are selecting data fromJoin tables using keys
(Primary / Foreign)Filter data wherever
possible.

• Procedures are different from scripts

78
SQL scripts
• Set of commands to run in sequence.
• Stored as a text file (e.g. using Notepad) on a disk
and not in the data dictionary. It is accessed by file
name
• Executed using @ or Start.

Script called:
Create_User.sql

Executed by:
SQL> @Create_User.sql
79
Procedures in SQL
Block of SQL statements stored in the Data dictionary and called
by applications or from SQL* plus prompt.
Usually used to implement application/business logic.
When called all code within a procedure is executed (unlike
packages).Action takes place on server side not client.
Do not return value to calling program.
Not available in Oracle 6 or older.
Adds security as DBA will grant access to procedures not tables,
therefore users can not access tables unless via a procedure.
The major difference between PL/SQL function or procedure,
function return always value where as procedure may or may not
return value.

80
How Oracle executes Procedures
• The Oracle engine checks if the user who called the procedures or
functions has the execute privilege for the procedure or functions.
• If the user is invalid,then access is denied otherwise the Oracle
engine proceeds to check whether the called procedures or function
is valid or not.
• The status of a procedure or function is seen by using a select
statement as follows.
– Verifies user access.
– Verifies procedure or function validity
– Executes the procedures or function.
• The Oracle engine checks if the user who called the procedures or
function has the execute privilege for the procedure or function.
– If the use is invalid ,then access is denied
– Otherwise Oracle engine proceeds to check whether the called
procedure or function is valid or not.
– The status of procedure or function is seen by using a select
statement.
– Select object_name,object_type,status
From user_objects
– Where object_type=‘procedure’
OR
Select object_name, object_type, status
From user_objects
Where objects_type=‘functions’;
If status is valid then functions and procedures atre executed.
Advantages using procedures and Functions
• Security-
– Enforces Data security
– By giving permission to a procedure or function that can query a table and
granting the procedure or function to users ,permissions to manipulate the
table itself need not be granted to users,permission to manipulate the table
itself need not be granted to users.
• Performance
– Amount of information sent over network is less.
– No compilation error is required to execute the code.
• Memory Allocation
– Shared memory capabilities
– Only one copy of procedure is needs to be loadedfor execution of multiple
users
• Productivity
– Redundant coding is avoided
• Integrity
– High level of in built security with Oracle engine
Building a procedure
1. Create or replace command
2. Type of object to be created
3. Name of object
4. Any variables accessed or imported
5. Declare local variables
6. Write body of the object (code)
7. End procedure declaration

85
Compiling and executing procedures
• Like any program the code needs to be compiled.
• @inflation_rise will compile the procedure and make it
available in the database
• Execute inflation_rise(2) will cause the procedure to
execute, with 2 as an inflation rate.
• Remember to compile a procedure once it has been
amended.
• For ease of use, it is easiest to write procedures in
notepad, store as script files, and then run them, this
means that they can be easily edited – also you will have
a copy if required

86
1. Create or replace This procedure is called inflation_rise and used a
command variable accessed as inf_rate which is a number,
this is passed in when the procedure is used. It
2. Object to be created simply updates the salary by the rate of inflation.
3. Name of object
4. Any variables accessed
or imported Create or replace procedure inflation_rise (inf_rate in
number)

5. Declare local variablesBegin

update employee
6. Body set salary = salary + (salary * inf_rate / 100);
commit;

7. End procedure End;


declaration

87
Example
CREATE OR REPLACE PROCEDURE validate_customer ( v_cust IN VARCHAR ) AS
v_count NUMBER;
Local variables used
BEGIN
Any variables
by procedure passed into
SQL SELECT COUNT(*) INTO V_COUNT
procedure
FROM customer
WHERE c_id = v_cust;
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE( 'customer valid');
ELSE
DBMS_OUTPUT.PUT_LINE('customer not recognised');
END IF;
END;

88
• A sequence is an object that is used to generate a list of numbers.
– They are very useful when we need unique numbers to populate id columns like friend_id in
FRIEND_NAME or phone_id in PHONE_NUMBER. The syntax for creating a sequence is
as follows:
– CREATE SEQUENCE friend_id_seq START WITH 100 INCREMENT BY 1;

• we create a procedure that will analyse our database for us and report on
the breakdown of our friends. We can call it something like
friends_analysis.
• CREATE OR REPLACE PROCEDURE friends_analysis
• AS BEGIN
• FOR i IN
• (SELECT COUNT(*) cnt, gender FROM friend_name GROUP BY gender)
• LOOP IF i.gender = 'M' THEN dbms_output.put_line('I have '||i.cnt||' male friends.');
• ELSIF i.gender = 'F' THEN dbms_output.put_line('I have '||i.cnt||' female friends.');
• END IF; END LOOP; /* Assume the value in friend_name.friend_id represents the order in
which we became friends. */
• FOR i IN
• (SELECT first_name, middle_name, last_name FROM friend_name
• WHERE friend_id = (SELECT MIN(friend_id) FROM friend_name ) )
• LOOP dbms_output.put_line('Our oldest friend is '||i.first_name||' '||i.middle_name||'
'||i.last_name);
• END LOOP;
• FOR i IN (SELECT first_name, middle_name, last_name FROM friend_name WHERE
friend_id = (SELECT MAX(friend_id) FROM friend_name ) ) LOOP
dbms_output.put_line('Our newest friend is '||i.first_name||' '||i.middle_name||' '||i.last_name);
END LOOP;
• END friends_analysis;
• When we run the code above it will not output an analysis of
our friends;
– instead it will create a procedure named friends_analysis in our
database, ready for us to use whenever we want to – and reuse as often
as we want.
• Procedures can be called from other procedures, from
anonymous blocks, from functions – wherever they’re needed
in your PL/SQL.
• Let’s call ours from an anonymous block.
• BEGIN friends_analysis;
• END;
• The fact that procedures – and functions – can be called repeatedly
from numerous places is what makes them so useful.
• Think about it: it saves the developer the trouble of all that typing; it
makes bug-fixing easier since you only need to correct an error in a
single place;
• if your requirement changes you only have to make a change in one place;
it makes code easier to read (the anonymous block above is only 3 lines
long – and yet it does so much!)
Parameters
• We’ve been throwing the word parameter around like it’s
confetti at a wedding.
• A parameter is a special kind of variable which is used to
pass data into a procedure or function.
• Earlier, we talked about creating a procedure that would
accept a new friend’s name and a phone number – as
parameters – and insert the details into the right tables.
• Let’s write it to illustrate the usefulness of parameters.
• CREATE OR REPLACE PROCEDURE
– insert_new_friend (pFirst_name VARCHAR2, pLast_name VARCHAR2, pGender
VARCHAR2, pPhone_country NUMBER, pPhone_area NUMBER, pPhone_number
NUMBER )
– AS -- declare our variables.
– v_friend_id NUMBER;
– v_phone_id NUMBER;
– BEGIN -- add a record to the friend_name table.
– INSERT INTO friend_name (friend_id, first_name, last_name, gender)
– VALUES (friend_id_seq.nextval, pFirst_name, pLast_name, pGender)
– RETURNING friend_id INTO v_friend_id;
– Next we need to add a new record to the PHONE_NUMBER table.
– INSERT INTO phone_number( phone_id, country_code, area_code,
phone_number)
– VALUES (phone_id_seq.nextval, pPhone_country, pPhone_area,
pPhone_number) RETURNING phone_id INTO v_phone_id; --
– Finally, we need to associate our new friend with this phone number.
– INSERT INTO friend_phone (friend_id, phone_id, start_date) VALUES
(v_friend_id, v_phone_id, SYSDATE); END insert_new_friend;
• And that’s it. So now if, at our party, we made a friend from London and
another from Lagos, Nigeria, we might simply call our procedure from an
anonymous block, passing in the right parameters.
• BEGIN
• insert_new_friend ('Jane', 'Simpson', 'F', 44, 207, 555551);
insert_new_friend ('Ola', 'Sanusi', 'M', 234, 1, 890555); END;
• By calling our new procedure with the names of our new friends,
• we are populating our parameters – pFirst_name, pLast_name etc –
• and so we can use them in our insert statements. This is how we are able to use the
exact same procedure for Jane Simpson, for Ola Sanusi and for however many new
friends we make in the future.
• There are a few other new things that I sneaked into our procedure:
– To get the next number from a sequence, we use the following syntax:
<sequence_name>.nextval. This always gets the next number;
– so if your sequence is at 100 and you call <sequence_name>.
– nextval three times in three select statements,
– you will (probably) get 101, 102 and 103.
– After you’ve run <sequence_name>.nextval, you can run <sequence_name>.currval to get the
current value, rather than the next one.
• The RETURNING … INTO clause can be used with insert and update
statements to place a value in a variable.
• In our procedure, we’re adding a new friend_id using friend_id_seq.nextval;
however, we want to assign that number to our v_friend_id variable so we can
use it later.
Why we CREATE OR REPLACE for creating a
stored procedure in PL/SQL?
CREATE OR REPLACE for creating a stored
procedure in PL/SQL?
• OR REPLACE allows you to replace a procedure
which already exists, in other words, you don’t need to
drop the procedure and recreate it each time you want to
recreate it.
• REPLACE KEYWORD Allows you to Modify Data Base
Objects Already exist.
– examples
CREATE PROCEDURE pr_greetings
IS BEGIN DBMS_OUTPUT.PUT_LINE('Hello');
END;

OUTPUT:
PROCEDURE PR_GREETINGS compiled
If we try to modify without REPLACE KEYWORD we get
error, SO i should drop it and Re-create it.

CREATE PROCEDURE pr_greetings ``


IS
BEGIN DBMS_OUTPUT.PUT_LINE('Hello World');
END;
OUTPUT: ORA-00955: name is already used by an existing object

REPLACE KEYWORD we can modify that


CREATE or REPLACE PROCEDURE pr_greetings
IS
BEGIN DBMS_OUTPUT.PUT_LINE('Hello World');
END; OUTPUT:
PROCEDURE PR_GREETINGS compiled.
If we try to modify without REPLACE KEYWORD we get error, SO should
drop it and Re-create it. To modify the procedure without 'create or replace'
you have to drop and recreate the object itself
Functions
• Functions, as we said earlier, must return a value.
• Basically, functions must answer a single, specific question. You can write a
function for the following:
• Find out a friend’s phone number
• Return a friend’s gender
• Test a premise. For example, return TRUE if you have a friend in London, or
FALSE if you don’t.
• But you cannot write a function for the following:
• Find a friend’s phone number and gender.
– Because functions must always answer a single, specific question. (It is
possible, using more complex datatypes to return a single value comprised
of other bits of information, but that is outside the scope of this series.)
– creating a function named get_friend_phone_number to answer the
specific question: what is the parameterised friend’s phone number.
• CREATE OR REPLACE FUNCTION get_friend_phone_number (pFirst_name
VARCHAR2, pLast_name VARCHAR2)
• RETURN NUMBER AS V_phone_no NUMBER;
Useful when updating or deleting each
row fetched in a cursor otherwise all
would be updated at once

SELECT FOR UPDATE Cursors


DECLARE
CURSOR c_salary IS SELECT surname,salary FROM Personnel
FOR UPDATE;
v_surname personnel.surname%TYPE;
v_salary personnel.salary%TYPE;
BEGIN
OPEN c_salary;
LOOP
FETCH c_salary INTO v_surname, v_salary;
EXIT WHEN c_salary%NOTFOUND;
UPDATE Personnel SET BONUS=v_salary*0.05 WHERE
CURRENT of c_salary;
END LOOP;
CLOSE c_salary;
101
END;
Stored Procedures
CREATE OR REPLACE PROCEDURE proc_name
IS
<declarations of variables, cursors etc> ……..
BEGIN
<executing code> …..
END proc_name;

• A unit of code that performs one or more tasks


• After completion, execution returns to the
calling block
• To run the procedure at any time, use
EXECUTE <procedure_name>
102
Example Procedure with a cursor

CREATE OR REPLACE PROCEDURE surnames


IS
CURSOR c_staff
IS
SELECT surname
FROM Personnel
where div=10;
BEGIN
FOR names IN c_staff LOOP
DBMS_OUTPUT.PUT_LINE(names.surname);
END LOOP
END;

The message ‘Procedure created’ should be displayed 103


Example Procedure to updateBlock3
salaries and how to test it

CREATE OR REPLACE PROCEDURE sal_update


IS
BEGIN
UPDATE personnel set salary=salary*1.1
where div=10;
END;

Execute sal_update;
Select salary from personnel where div=10;
- to test the procedure

104
Example Procedure to updateBlock3
salaries and how to test it

CREATE OR REPLACE PROCEDURE sal_update


IS
BEGIN
UPDATE personnel set salary=salary*1.1
where div=10;
END;

Execute sal_update;
Select salary from personnel where div=10;
- to test the procedure

105
Passing parameters

Parameter nameParameter mode datatype

CREATE OR REPLACE PROCEDURE test


(firstpar IN varchar2,
secondpar IN Date) Notice
IS parameter
empname varchar2(30); declarations
empid number(8); are
BEGIN
unconstraine
……..
END; d

IN is the default if no mode specified 106


IN

CREATE OR REPLACE PROCEDURE t This is legal as parameter is


( p_salary IN Number) assigned to a variable first
IS
BEGIN
……..
p_salary:=p_salary + 100;
CREATE OR REPLACE PROCEDURE t
END;
( p_salary IN Number,
IS
This is illegal as parameter can only v_salary number(15);
be referenced, not changed BEGIN
……..
v_salary:=p_salary + 100;
END; 107
Block4
IN Example

CREATE OR REPLACE PROCEDURE proc_IN


( p_branchNumber IN Number,
p_percent IN Number)
IS
BEGIN
UPDATE Personnel set
salary=salary+salary*p_percent/100
where div = p_branchNumber;
END;

EXECUTE proc_IN(10,25)

108
Actual andEXECUTE
Formal parameters
updperc(10,3455)

CREATE OR REPLACE PROCEDURE updperc


( p_percent IN Number, Formal
p_Emp IN Number)
IS CREATE OR REPLACE
CURSOR staff_cur IS PROCEDURE updstaff
SELECT joindate, div ( p_joindate IN Date,
from Personnel p_div IN Number)
where managedBy=p_Emp; IS
BEGIN ….
For stf in staff_cur LOOP
updStaff(stf.joindate,stf.div); The Calling Procedure
END LOOP;
… Actual
END;
109
Another Calling Example Block5

DECLARE
v_var NUMBER := 20; Anonymou
BEGIN s block
delete_staff(v_var);
END;
calls
procedure
CREATE OR REPLACE PROCEDURE delete_staff
(p_branchNumber IN Number)
IS
BEGIN
DELETE Personnel
WHERE div=p_branchNumber;
END;
110
Using parameters in Loops

CREATE OR REPLACE PROCEDURE


insert_root (from_val NUMBER, to_val NUMBER)
IS
num NUMBER;
BEGIN
FOR num IN from_val .. to_val LOOP
INSERT INTO roots VALUES (num, SQRT(num));
END LOOP;
END;

To execute this procedure (e.g insert values from 30 to 32)

EXECUTE insert_root(30,32)
111
FUNCTIONS
• Functions are similar to procedures
• They are used for calculations and returning
a value

CREATE OR REPLACE FUNCTION Can be:


function_name (parameter list) NUMBER
RETURN return_datatype VARCHAR2
IS BOOLEAN
… variables, cursors etc etc
BEGIN
Execution code ………………;
Return expression;
END;
112
RETURN Statement

• Determines
– The point at which execution returns to the
calling block AND the value that is assigned to it
• RETURN expression
– Where expression can be any legal PL/SQL
expression
v_salary := get_salary(10)
Block calls the function get_salary for employee 10
Get_salary will return the salary for employee 10 and this will be
assigned to v_salary
113
CREATE OR REPLACE FUNCTION
get_aveSal
Block6 (i_div IN NUMBER)
RETURN number
IS
Example Function v_salary
personnel.salary%type;
BEGIN
SELECT avg(salary)
INTO v_salary FROM
Personnel
WHERE div=i_div;
SET SERVEROUTPUT ON RETURN v_salary;
DECLARE END get_aveSal;
V_divID personnel.div%type;
v_divName branch.DivName%type:='&divName';
V_aveSalary personnel.salary%type;
BEGIN "get the average
SELECT div into v_divID salary for ADMIN"
FROM branch WHERE divname=v_divName; Block prompts for
v_aveSalary:=get_aveSal(v_divID); division name then
DBMS_OUTPUT.PUT_LINE('Division '||v_divID||' has passes the division
'||v_aveSalary||' average salary'); number to the
END; function get_aveSal
114
DATABASE TRIGGERS
What is a database trigger?
Types of Triggers
 Creating a database trigger
What is a Database Trigger?
Database trigger is a PL/SQL block that is executed on
an event in the database.
The event is related to a particular data manipulation
of a table such as inserting, deleting or updating a row
of a table.
Triggers may be used for any of the following:
To implement complex business rule, which cannot be
implemented using integrity constraints.
To audit the process. For example, to keep track of
changes made to a table.
To automatically perform an action when another
concerned action takes place.
• A database trigger is special stored procedure that is run when
specific actions occur within a database.
• Most triggers are defined to run when changes are made to a
table’s data.
– Triggers can be defined to run instead of or after DML (Data Manipulation
Language) actions such as INSERT, UPDATE, and DELETE.
• Triggers help the database designer ensure certain actions, such as
maintaining an audit file, are completed regardless of which
program or user makes changes to the data.
• The programs are called triggers since an event, such as adding a
record to a table, fires their execution.
Cont…
updating a table whenever there is an insertion
or a row into another table.
Triggers are similar to stored procedures, but
stored procedures are called explicitly and
triggers are called implicitly by Oracle(upon
modification of an associated table or its data) when
the concerned event occurs.
Note: Triggers are automatically executed by
Oracle and their execution is transparent to
users.
A trigger is defined for a specific table and one or more events. In most
database management systems you can only define one trigger per table.
Types of Triggers

• Depending upon, when a trigger is fired, it


may be classified as :
• Statement-level trigger
• Row-level trigger
• Before triggers
• After triggers
Statement-level Triggers
A statement trigger is fired only for once for a DML statement
irrespective of the number of rows affected by the statement.
For example, if you execute the following UPDATE command
STUDENTS table, statement trigger for UPDATE is executed only
for once.
update students set bcode =’b3’
where bcode = ‘b2’;
statements triggers cannot be used to access the data that is being
inserted, updated or deleted.
In other words, they do not have access to keywords NEW and OLD, which are
used to access data.
Statement-level triggers are typically used to enforce rules that are not related to
data.
For example, it is possible to implement a rule that says “no body can modify
BATCHES table after 9 P.M”.
Statement-level trigger is the default type of trigger
Row-level Trigger
 A row trigger is fired once for each row that is
affected by DML command.
For example:-
 if an UPDATE command updates 100 rows then row-
level trigger is fired 100 times whereas a
 statement-level-
 Trigger is fired only for once .Row-level trigger are
used to check for the validity of the data.
 They are typically used to implement rules that
cannot be implemented by integrity constraints.
 Row-level triggers are implemented by using the
option FOR EACH ROW in CREATE TRIGGER
statement.
We have a trigger that will make sure all high school seniors
graduate. That is, when a senior's grade is 12, and we increase
it to 13, we want to set the grade to NULL.
and a row-level trigger would look like
create trigger this:
stmt_level_trigger create trigger row_level_trigger
after update on Highschool
after update on Highschool
for each row
begin when New.grade = 13
update Highschool begin
set grade = NULL update Highschool
where grade = 13; set grade = NULL
where New.ID = Highschool.ID;
end;
End;

statement level trigger would be able to row-level trigger may be used to


modify one row, update/delete/insert many rows as well. Or
rows in other tables.

And a statement-level trigger too


Statement-level trigger and Row level
trigger
• If want to execute the statement when
number of rows are modified then it can be
possible by statement level triggers.Vice-
versa...
• when you want to execute your statement
each modification on your number of rows
then you need to go for row level triggers..
Before Triggers
While defining a trigger, you can specify whether
the trigger is to be fired before the command
(INSERT, DELETE, and UPDATE) is executed
or after the command is executed.
Before triggers are commonly used to check the
validity of the data before the action is performed.
For instance, you can use before trigger to prevent
deletion of row if deletion should not be allowed in
the given case.
AFTER Triggers
• After triggers are fired after the triggering action
is completed.
– For example, If after trigger is associated with
INSERT command then it is fired after the row is
inserted into the table.
Possible Combinations
• The following are the various possible
combinations of database triggers.
• Before Statement
• Before Row
• After Statement
• After Row
How to create MySQL triggers
• A trigger is a named database object that is associated with a
table, and it activates when a particular event (e.g. an insert,
update or delete) occurs for the table.
• The statement CREATE TRIGGER creates a new trigger in
MySQL. Here is the syntax :
• Syntax:
• The DEFINER clause specifies the MySQL account to be used when checking access
privileges at trigger activation time.

CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name


trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_body
trigger_time:
{ BEFORE | AFTER } trigger_event: { INSERT | UPDATE | DELETE }
Creating a Database Trigger
• CREATE TRIGGER command is used to create a
database trigger.
• The following details are to be given at the time of
creating a trigger.
• Name of the trigger
• Table to be associated with
• When trigger is to be fired - before or after
• Command that invokes the trigger - UPDATE,
DELETE, or INSERT Whether row-level trigger or
not Condition to filter rows.
PL/SQL block that is to be executed when trigger is
fired.
Syntax
• CREATE [OR REPLACE] TRIGGER
triggername
• {BEFORE | AFTER}
• {DELETE | INSERT | UPDATE [OF columns]}
• [OR {DELETE | INSERT |UPDATE [OF
columns]}]...
• ON table
• [FOR EACH ROW [WHEN condition]]
• [REFERENCING [OLD AS old] [NEW AS new]]
• PL/SQL block
For example
The following trigger is fired only when
AMOUNT is more than 1000.
• create or replace trigger ..
• before insert on payments
• for each row
• when :new.amount > 1000
The following is a simple database trigger that is used to
check whether date of joining of the
student is less than or equal to system date.
(Otherwise it raises an error).
Create or replace trigger students_bi_row .
before insert on students
for each row
begin
if :new.dj > sysdate then
raise_application_error
(-20002,'Date of joining cannot be after system
date.');
end if;
end;
• Trigger has to be fired when an update or
delete is fired on the table client_master.
– The trigger first checks for the operations being
performed on the table.
– Then depending on the operations being
performed,a varable is assigned the value
‘update’ or ’delete’.
• Previous values of the modified record of the
table client_master are stored into
appropriate variables declared,
• The content of this variables are then inserted
into the audit table audit client
CREATE TRIGGER audit_trail
AFTER UPDATE OR DELETE ON client_master
FOR EACH ROW
DECLARE
/*The value in the oper varable will be inserted into the operation field
in the auditclient table*/
Oper varchar2(8);
/*These variables will hold the previous values of client_no,name and
bal_due */
Client_no varchar2(6);
Name varchar2(20);
Bal_due number(10,2);
BEGIN
/*if the records are updated in client_master table
then oper is set to update */
IF updating THEN
oper :=‘update’;
ENDIF;
/* if the records are deleted in client_master table
then oper is set to delete */
IF deleting THEN
oper :=‘delete’
END IF ;
/* Store :old.client_no, :old.name.and old.bal_due into
client_no,name and bal_due.These variables can then be
used to insert data into the auditclient table */
Client_no := old.client_no;
Name :=: old.name;
Bal_due :=: old.bal_due;
INSERT INTO auditclient
VALUES
(client_no,name,bal_due,oper,user,sysdate);
END;
Statement –level trigger
• Consider here a trigger date_stamp is created on
reserv_detail table.which acts after updation of each
row.After every updation on the table for each row
the trigger fires and shows the date updation.
– CREATE TRIGGER date_stamp AFTER UPDATE ON
reserv_detais FOR EACH ROW
– BEGIN
– DBMS_OUTPUT.PUT_LINE (‘The date of updation’||
sysdate);
– END
After updation
Update reserve_details
SET reserve_status = ‘W’
WHERE passenger_id =‘p005’;

OUTPUT
The date of updation 17 april-00
1 row updated.
Conditional Option
• Triggers for multiple INSERT,UPDATE AND
DELETE command can be combined into a
single trigger, provided they all at same level.
• i.e row level or statement level.
• Conditional options can be used to distinguish
Between which operation caused the trigger to
be fired. The valid conditional options are
inserting ,Deleting and updating.
Example
• Create a trigger called pass_audit that keep
details of all the changes made upon the table
passengers_detail.
• But before we create the trigger we have to
create table detail into which trigger will store
the data.
• The detail table will store the DML action ,date
-manipulation,old and new passenger_id .Hence
we can create table
• Create table details
Action varchar2(20);
day DATE,
old_pass_id varchar2(4)
new_pass_id varchar2(4)
Create a Triggers
CREATE TRIGGER pass_audit AFTER INSERT OR
UPDATE OR DELETE ON passengers_detail FOR
EACH ROW
DECLARE
Action varchar2(20);
• BEGIN
IF UPDATING THEN
Action := ‘update’
INSERT INTO details VALUES
(action,SYSDATE,OLD.passenger_id,null);
ENDIF
IF INSERTING THEN
action := ‘insert’
INSERT INTO detail VALUES
(action,SYSDATE,NULL,:NEW.passenger-id);
END IF;
END;
ONCE TRIGGER IS CREATED LET US
MANIPULATE INSERT ,DELETE,
UPDATE
• INSERT INTO PASSENGERS_DETAILS VALUES
(‘P009’,’SUDIP’,23,’M’.’123
SRINIVASPURI’,’DELHI’
’SUDIP@INFOTECH.COM’.’499111’,’CREDIT
CARD’ ‘28000’);
• DELETE FROM PASSENGERS_DETAILS WHERE
pasenger_id=‘p002’;
• UPDATE passengers_details SET passenger_id
=‘p002’ WHERE passenger_id;
Select * from details;
• ACTION DAY OLD_ NEW
• -------------------------------------------------------------
• Insert 05-APRIL-15 p009
• Delete 05-APRIL-15 p002
• Update 05-APRIL -15 p009 p002

• All the transactions done are shown.


Modifying Triggers
• A trigger can be created using the CREATE
statement.
• As with other subprograms, a CREATE
statement will fail if an object already exists.
We can override this behavior by using the
Oracle proprietary REPLACE keyword.
• This allows an existing subprogram (in this
case a trigger) to be modified without having
to drop it and then recreate it.
Exercise-01
• Create a trigger to raise an error if an employee salary being entered is
greater than 25000.
• Name the trigger TR_VALIDATE_SALARY.
• The trigger should reference the SALARY field on the EMPLOYEES
table.
• Test the trigger by verifying that you can set the salary of employee_id 100
to an acceptable value but that an error occurs if the salary is above 25000.
• Drop the trigger when you have finished testing.
Create or replace trigger tr_validate_salary
before insert or update of salary on employees for each row begin
IF :new.salary > 25000 THEN raise_application_error(-20001, 'Invalid Salary: ' ||
:new.salary);
END IF; end; / -- Watch it fail update employees set salary=28000 where
employee_id=100; --
Watch it succeed update employees set salary=21000 where employee_id=100; --
rollback the change before executing the DDL rollback; -- drop the trigger drop
trigger tr_validate_salary;
Constraints versus Triggers
• Constraints are useful for database consistency
– Use IC when sufficient
– More opportunity for optimization
– Not restricted into insert/delete/update
• Triggers are flexible and powerful
– Alerters
– Event logging for auditing
– Security enforcement
– Analysis of table accesses (statistics)
– Workflow and business intelligence …
• But can be hard to understand ……
– Several triggers (Arbitrary order  unpredictable !?)
– Chain triggers (When to stop ?)
– Recursive triggers (Termination?)
Trigger/cursor
• Trigger is an event driven PL/SQL block. Event
may be any DML transaction.

Cursor is a stored select statement for that


current session. It will not be stored in the
database, it is a logical component.

Function is a set of PL/SQL statements or a


PL/SQL block, which performs an operation and
must return a value.
Use the following guidelines when designing your triggers:
• Use triggers to guarantee that when a specific operation is performed, related
actions are performed.
– Do not define triggers that duplicate features already built into Oracle Database. For
example, do not define triggers to reject bad data if you can do the same checking
through declarative integrity constraints.
• Limit the size of triggers. If the logic for your trigger requires much more than 60
lines of PL/SQL code, it is better to include most of the code in a stored
procedure and call the procedure from the trigger.
– Use triggers only for centralized, global operations that should be fired for
the triggering statement, regardless of which user or database application
issues the statement.
• Do not create recursive triggers.
– For example, creating an AFTER UPDATE statement trigger on
the Emp_tab table that itself issues an UPDATE statement on Emp_tab, causes
the trigger to fire recursively until it has run out of memory.
• Use triggers on DATABASE judiciously. They are executed
for every user every time the event occurs on which the trigger is created
Assertions

160
Assertion
• Most relational database management systems
(RDBMS) do not implement assertions.
• Assertions are similar to check constraints, but
unlike check constraints they are not defined on
table or column level but are defined on
schema level.
• (i.e., assertions are database objects of their own
right and are not defined within a create table or
alter table statement.)
• The SQL syntax for create assertion is:
• CREATE ASSERTION <constraint name>
CHECK (<search condition>)
• An assertion is a named constraint that
may relate to the content of individual
rows of a table, to the entire contents of a
table, or to a state required to exist
among a number of tables.
In addition to the components of
every constraint descriptor an
assertion descriptor includes:
the <search condition>.
An assertion is satisfied if and only if
the specified <search condition> is not
false.
Assertions
• An assertion is a predicate expressing a
condition that we wish the database always to
satisfy.An assertion in SQL takes the form
create assertion <assertion-name> check
<predicate>
• When an assertion is made, the system tests it
for validity, and tests it again on every update
that may violate the assertion
– This testing may introduce a significant
amount of overhead; hence assertions should
be used with great care.
Assertions
An expression that should be always
true,When created, the expression must
be true.
DBMS checks the assertion after any
change that may violate the expression

Must return True or False


165
• CREATE SCHEMA bob CREATE TABLE bob.Table_1 (column_1
SMALLINT)
• CREATE ASSERTION bob.constraint_1 CHECK ((SELECT
AVG(column_1) FROM Table_1 >40) NOT DEFERRABLE; --
– creates an Assertion called BOB.CONSTRAINT_1 in Schema BOB
Assertions: An Example 1
• “The salary of an employee must not be
greater than the salary of the manager of the
department that the employee works for’’
CREAT ASSERTION SALARY_CONSTRAINT
CHECK (NOT EXISTS (SELECT *
FROM EMPLOYEE E, EMPLOYEE M, DEPARTMENT D
WHERE E.SALARY > M.SALARY AND
E.DNO=D.NUMBER AND D.MGRSSN=M.SSN))

Chapter 9-167
Using General Assertions
• Specify a query that violates the condition;
include inside a NOT EXISTS clause
• Query result must be empty
– if the query result is not empty, the assertion has
been violated

Chapter 9-168
Example 2

Sum of loans taken by a customer does not exceed


100,000 Must return True or False
(not a relation)
Create Assertion SumLoans Check
( 100,000 >= ALL
Select Sum(amount)
From borrower B , loan L
Where B.loan_number = L.loan_number
Group By customer_name );

169
Example 3

Number of accounts for each customer in a given branch is at


most two

Create Assertion NumAccounts Check


( 2 >= ALL
Select count(*)
From account A , depositor D
Where A.account_number = D.account_number
Group By customer_name, branch_name );

170
Example 4

Customer city is always not null

Create Assertion CityCheck Check


( NOT EXISTS (
Select *
From customer
Where customer_city is null));

171
Assertions vs. Triggers
 Assertions do not modify the data, they only check certain conditions

 Triggers are more powerful because the can check conditions and also
modify the data

 Assertions are not linked to specific tables in the database and not linked
to specific events

 Triggers are linked to specific tables and specific events


Assertions vs. Triggers (Cont’d)
 All assertions can be implemented as triggers
(one or more)

 Not all triggers can be implemented as assertions


Example: Trigger vs. Assertion
All new customers opening an account must have opening balance >= $100. However, once
the account is opened their balance can fall below that amount.

Trigger Event: Before Insert


We need triggers, assertions cannot be used

Create Trigger OpeningBal


Before Insert On Customer
For Each Row
Begin
IF (:new.balance is null or :new.balance < 100) Then
RAISE_APPLICATION_ERROR(-20004, 'Balance should be >= $100');
End IF;
End;
Assertion Example
• The sum of all loan amounts for each branch
must be less than the sum of all account
balances at the branch.
create assertion sum-constraint check
(not exists (select * from branch
where (select sum(amount) from
loan where loan.branch-name =
branch.branch-name)
>= (select sum(amount) from
account where loan.branch-name =
branch.branch-name)))
Assertion Example
• Every loan has at least one borrower who maintains an account
with a minimum balance or $1000.00
create assertion balance-constraint check
(not exists (
select * from loan
where not exists (
select *
from borrower, depositor, account
where loan.loan-number = borrower.loan-number
and borrower.customer-name = depositor.customer-name
and depositor.account-number = account.account-number
and account.balance >= 1000)))
Difference between Triggers Check and
Assertions
• Triggers - a trigger is a piece of SQL to execute
either before or after an update, insert, or
delete in a database. An example of a trigger
in plain English might be something like:
before updating a customer record, save a
copy of the current record
• The difference between assertions and checks
is a little more murky, many databases don't
even support assertions.
• Check Constraint - A check is a piece of SQL
which makes sure a condition is satisfied
before action can be taken on a record. In
plain English this would be something like:
• All customers must have an account balance
of at least $100 in their account
• Any attempt to insert a value in the balance column of less than 100
would throw an error.
• Assertions - An assertion is a piece of SQL which makes sure a
condition is satisfied or it stops action being taken on a database
object.
• It could mean locking out the whole table or even the whole database.
• To make matters more confusing - a trigger could be used to enforce a
check constraint and in some DBs can take the place of an assertion
(by allowing you to run code un-related to the table being modified). A
common mistake for beginners is to use a check constraint when a
trigger is required or a trigger when a check constraint is required.
• An example: All new customers opening an account must have a
balance of $100; however, once the account is opened their balance can
fall below that amount. In this case you have to use a trigger because
you only want the condition evaluated when a new record is inserted.

S-ar putea să vă placă și