0% found this document useful (0 votes)
51 views48 pages

Lecture6 4-PLSQL2

Triggers automatically execute a PL/SQL block when a triggering event such as an insert, update, or delete occurs on a table. They are defined using the CREATE TRIGGER statement and can access old and new row values using correlation names. Cursor attributes like %ISOPEN and %FOUND provide status information about a cursor, which allows row-by-row processing of a multi-row query result. Cursors are declared and then opened, fetched from, and closed to iterate through rows.

Uploaded by

afzhussain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views48 pages

Lecture6 4-PLSQL2

Triggers automatically execute a PL/SQL block when a triggering event such as an insert, update, or delete occurs on a table. They are defined using the CREATE TRIGGER statement and can access old and new row values using correlation names. Cursor attributes like %ISOPEN and %FOUND provide status information about a cursor, which allows row-by-row processing of a multi-row query result. Cursors are declared and then opened, fetched from, and closed to iterate through rows.

Uploaded by

afzhussain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 48

CPSC 4670 Database Security

and Auditing
Oracle PL/SQL: Triggers

1
Triggers

 An SQL trigger is a mechanism that


automatically executes a specified PL/SQL
block when a triggering event occurs on a
table.
 The triggering event may be one of insert,
delete, or update.
 The trigger is associated with a database
table and is fired when the triggering event
takes place on the table.
2
Triggers
create [or replace] trigger trigger-name
{before | after}
{delete | insert | update [of column [, column] …]}
[or
{delete | insert | update [of column [, column …]}
]…
ON table-name
[ [referencing {old [as] <old> [new [as] <new>]
| new [as] <new> [old [as] <old> }]
for each row
[when (condition)] ]
pl/sql_block

3
Triggers
 referencing specifies correlation names that
can be used to refer to the old and new
values of the row components that are being
affected by the trigger
 for each row designates the trigger to be a
row trigger, i.e., the trigger is fired once for
each row that is affected by the triggering
event and meets the optional trigger
constraint defined in the when clause.
 when specifies the trigger restriction.
4
Trigger example
 A trigger is executed when a row is inserted
into the odetails table.
 The trigger checks to see if the quantity
ordered is more than the quantity on hand.
If it is, an error message is generated, and
the row is not inserted.
 Otherwise, the trigger updates the quantity
on hand for the part and checks to see if it
has fallen below the reorder level. If it has,
it sends a row to the restock table indicating
that the part need to be reordered.
5
Trigger example

 trig2.sql
 trig2test.sql

 SQL> start trig2test

Then double check the restock table and


part table for the results of trig2.sql

6
Trigger example (2)
 The trigger is defined on the parts
table and is triggered when the price
column is updated. Each time
someone updates the price of a
particular part, the trigger makes an
entry in a log file of this update along
with the userid of the person
performing the update and the date of
the update.
7
Trigger example (2)

 The log file is created using


Create table parts_log(
pno number(5),
username char(8),
update_date date,
old_price number(6,2),
new_price number(6,2))
8
Trigger is defined as

 trig3.sql
 SQL>update parts set price = 55.00
where pno = 1099;
 SQL> select * from parts_log;
 Use trig_tables.sql to test trig3.sql

9
Database Access Using
Cursors

10
Database Access Using
Cursors
 When the result of an SQL query
(select statement) consists of more
than one row, the simple select into
statement can not be used.
 A PL/SQL cursor allows the program to
fetch and process information from the
database into the PL/SQL program,
one row at a time.
11
Explicit Cursor
 Explicit cursor: used for processing a
query resulting in more than one row.
 Implicit cursor: is automatically defined
by PL/SQL for the select into statements,
which result in one or fewer rows.

cursor <cname> [return-spec] is


<select-statement>;
12
Cursor Example

cursor c1 return customers%rowtype is


select * from customers;
has return clause

cursor c2 is
select pno, pname, price*markdown
sale_price
from parts Use PL/SQL variable
markdown 13
Process cursor

 One a cursor has been declared, it can


be processed using the open, fetch, and
close statements.

open <cname>;
fetch <cname> into <Record-or-VariableList>;
close <cname>;

14
Explicit 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
15
rows returned so far.
Creating a Cursor
 We create a Cursor when we want to go over a result of
a query (like ResultSet in JDBC)
 Syntax Example:
sailorData is a
variable that
DECLARE can hold a
cursor c is select * from sailors; ROW from
sailorData sailors%ROWTYPE; the sailors
table

BEGIN
open c; Here the
fetch c into sailorData; first row of
sailors is
inserted into
16
sailorData
Cursor Example
RAD_VALS DECLARE
DECLARE
PiPiconstant
constantNUMBER(8,7)
NUMBER(8,7):= :=3.1415926;
3.1415926;
area
areaNUMBER(14,2);
NUMBER(14,2);
cursor
cursorrad_cursor
rad_cursorisisselect
select**from
fromRAD_VALS;
radius rad_val
RAD_VALS;
Rad_cursor rad_valrad_cursor%ROWTYPE;
rad_cursor%ROWTYPE;
3 BEGIN
BEGIN
f open
openrad_cursor;
rad_cursor;
e 6
fetch
fetchrad_cursor
rad_cursorinto
intorad_val;
rad_val;
area:=pi*power(rad_val.radius,2);
area:=pi*power(rad_val.radius,2);
t insert
insertinto
intoAREAS
AREASvalues
values(rad_val.radius,
(rad_val.radius,area);
area);
c 8 close rad_cursor;
close rad_cursor;
END;
END;
h //
Rad_val

AREAS
Radius Area 17

3 28.27
DECLARE
DECLARE DECLARE
DECLARE
…… ……
cursor
cursorrad_cursor
rad_cursorisisselect
select**from
fromRAD_VALS; cursor
rad_val rad_cursor%ROWTYPE;
RAD_VALS; cursorrad_cursor
rad_cursorisisselect
select**from
fromRAD_VALS;
RAD_VALS;
rad_val rad_cursor%ROWTYPE; rad_val RAD_VALS.radius%TYPE;
BEGIN rad_val RAD_VALS.radius%TYPE;
BEGIN BEGIN
open
openrad_cursor;
rad_cursor; BEGIN
fetch open
openrad_cursor;
rad_cursor;
fetch rad_cursorinto
rad_cursor intorad_val;
rad_val;
area:=pi*power(rad_val.radius,2);
area:=pi*power(rad_val.radius,2); fetch
fetchrad_cursor
rad_cursorinto
intorad_val;
rad_val;
insert
insertinto
intoAREAS
AREASvalues
values(rad_val.radius,
(rad_val.radius, area:=pi*power(rad_val,2);
area:=pi*power(rad_val,2);
area); insert
area); insertinto
intoAREAS
AREASvalues
values(rad_val,
(rad_val,area);
area);
…… ……

DECLARE
DECLARE DECLARE
DECLARE
…… ……
cursor
cursorrad_cursor
rad_cursorisisselect
select**from
fromRAD_VALS;
RAD_VALS; cursor
cursorrad_cursor
rad_cursorisisselect
selectradius
radiusfrom
from
rad_val
rad_valRAD_VALS%ROWTYPE;
RAD_VALS%ROWTYPE;
BEGIN RAD_VALS;
RAD_VALS;
BEGIN
open rad_val
rad_valRAD_VALS.radius%TYPE;
openrad_cursor;
rad_cursor; RAD_VALS.radius%TYPE;
fetch BEGIN
fetch rad_cursorinto
rad_cursor intorad_val;
rad_val; BEGIN
area:=pi*power(rad_val.radius,2); open
openrad_cursor;
rad_cursor;
area:=pi*power(rad_val.radius,2);
insert fetch
fetch rad_cursorinto
rad_cursor intorad_val;
insertinto
intoAREAS
AREASvalues
values(rad_val.radius,
(rad_val.radius, rad_val;
area);
area); area:=pi*power(rad_val,2);
area:=pi*power(rad_val,2);
…… insert
insertinto
intoAREAS
AREASvalues
values(rad_val,
(rad_val,area);
area);…

18
Cursor Example
 Use of the cursor statements and
attributes
 p7.sql

19
Cursor for loop
 This loop is very useful when all rows of the
cursors are to be processed.
for <record_index> in <cname> loop
<loop-body>;
end loop;
 <record_index> is a record variable that is
implicitly declared by PL/SQL. Its scope is
the for loop, and it can not be accessed
outside the for loop.
20
Cursor for loop

 The loop terminates automatically


when all rows of the cursor have been
fetched.
 There is no need to open, fetch, or
close the curse, and there is no need
to declare the record into which the
cursor rows are to be fetched.

21
Cursor for loop example
declare
cursor c1 is c1_rec
select cno, cname, city No declare for the
from customers, zipcodes record into which the
where customers.zip = zipcodes.zip; cursor rows are to be
fetched
begin
for c1_rec in c1 loop
dbms_output.put-line(‘Row number ’ || c1%rowcount
|| ‘> ‘ || c_rec.cno || ‘ ‘ || c1-rec.cname || ‘ ‘ ||
c1_rec.city);
end loop
end;
22
Parameterized Cursors

 PL/SQL allows for cursors to take input


parameters.
cursor <cname> (<parameter-list>)
[return <return-spec>]
is <select-statement>
 The parameters are specified
immediately after the cursor name
23
Parameterized Cursors
Cursor c3(city_in zipcodes.city%type) is
select orders.eno, ename, sum(qty*price) Sale
from employees, orders, odetails, parts, zipcodes
where employees.eno = orders.eno and
orders.ono = odetails.ono and
odetails.pno = parts.pno and
employees.zip = zipcodes.zip and
zipcodes.city = city_in
Group by order.eno, ename

Given a city, this cursor returns the sales totals for


every employee from that city
24
Parameterized Cursors
 The open statement for such cursors
will have the actual augment.
open ci3(‘Wichita’);
 If a cursor loop is used to process this
cursor
for c3_rec in c3(‘Wichita’) loop

end loop;
25
select for update
 PL/SQL cursors can also be used to perform
updates
cursor <cname> is
<select-statement> for update;
 Select statement should involve only one database
table
update <table-name>
set <set-clause>
where current of <cname>;

delete from < table-name >


where current of <cname>;
26
Example

 The price of every part whose


quantity-on-hand value is more than
175 is set to 80% of its old price.
 p8.sql

27
Cursor variables
 Cursor variables are not required to have
the SQL select statement associated with
them at the time of their declaration.
 Different SQL select statements can be
associated with cursor variables at
different times.
type <cursor-var-type-name> is ref cursor
[return <return-type>];
28
Cursor variables example

 Display the table whose name is an input


parameter
 A cursor variable is declared, with its
return type not state in the declaration.
 p9.sql
 SQL> execute display_table(‘customers’)
 SQL> execute display_table(‘abcd’)
29
Records and Tables

30
Records
 Table-based records, whose structure is
the same as that of a row in a database
table. p10.sql
 Cursor-based records is based on the
select list of a cursor. p11.sql
 Programmer defined records. A type
declaration is needed before record
variables can be declared. p12.sql
31
Table-based records
DECLARE
customer_rec customers%rowtype;
BEGIN
select *
into customer_rec
from customers
where cno = '4444';
if (customer_rec.phone is null) then
dbms_output.put_line('Phone number is absent');
else
dbms_output.put_line('Phone number is ' || customer_rec.phone);
end if;
END;
/

32
Cursor-based records
DECLARE
cursor c1 is BEGIN
select orders.eno employee_no, open c1;
ename employee_name, loop
sum(price*qty) total_sales fetch c1 into emp_sales_rec;
from exit when c1%NOTFOUND;
employees,orders,odetails,parts dbms_output.put_line(
where employees.eno = emp_sales_rec.employee_no || '
orders.eno ' || emp_sales_rec.employee_name ||
and ' ' || emp_sales_rec.total_sales);
orders.ono = odetails.ono end loop;
and close c1;
odetails.pno = parts.pno END;
group by orders.eno, ename; /

emp_sales_rec c1%rowtype;

33
Programmer defined records
DECLARE
TYPE my_rec_type IS RECORD
(number integer,
name varchar2(20));

r1 my_rec_type;
r2 my_rec_type;
BEGIN
r1.number := 111;
r1.name := 'jones';
r2 := r1;
dbms_output.put_line('Number = ' || r2.number ||
' Name = ' || r2.name);
END;
/
34
PL/SQL Tables

 PL/SQL tables always consist of just one


column indexed by binary integer
 They are sparse and provide direct
access to these rows, much like a hash
table.
type <table-type-name> is table of <datatype>
Index by binary_integer

35
Operations of tables
 count returns the number of elements in the
table. n := the_table.count;
 delete deletes the specified row or all rows.
the_table.delete(43);
 exists returns true if there exists a row in the
specified index, otherwise, it returns false. If
the_table.exists(3) then …
 first returns the lowest-valued index
 last returns the highest-valued index
 next returns the next-higher-valued index
 prior returns the next-lower-valued index
36
Table example
 Retrieves information from the Oracle data
dictionary table user_tab_columns and
prints the relational schemas of tables
whose names start with the letter “Z”
 p13.sql
 SQL> start p10

37
Built-In Packages

 dbms_output for debugging purpose


 dbms_sql is used for executing
dynamic SQ and PL/SQL statements

38
dbms_output package
 dbms_output package allows the user
to display information to the session’s
output device as the PL/SQL program
executes.
 disable all calls to the dbms_output
package.
dbms_output.disable
SQL> set serverouput off
39
dbms_output package

 enable enables all calls to the


dbms_output package.
dbms_output.enable(1000000) will
initialize the buffer size to 1000000.
Or dbms_output.enable;
SQL> set serveroutput on size 1000000
SQL> set serveroutput on
40
dbms_output package
 new_line inserts an en-of-line marker in the
buffer.
 put puts information into the buffer.
 put-line is the same as put, except that an
end-of-line marker is also placed in the
buffer.
 get_line retrieves one line of information
from the buffer.
 get_lines retrieves a specified number of
lines from the buffer.
41
dbms_sql Package

 Execute nonquery statements


– Open the cursor
– Parse the statement
– Bind any input variables
– Execute the statement
– Close the cursor
 p18.sql

42
dbms_sql Package
 Executing Queries
– Open the cursor
– Parse the statement
– Bind any input variables
– Define the output variables
– Execute the query
– Fetch the rows
– Return the results to PL/SQL variables
– Close the cursor
43
dbms_sql Package
 p20.ql creates a package dsql with two
procedures get_columns and
get_query_results.
 p21.sql creates a package dsql_driver with
two procedures and uses the types and
procedures get_columns and
get_query_results in p20.sql.
 p22.sql is an anonymous PL/SQL block that
calls procedures drive_get_query_results
from package dsql_driver in p21.sql
44
Error Handling
 PL/SQL implements run-time error handling
via exceptions and exception handlers.
when <exception-name> then
<Error-Handling-Code>
 User defined exception

<exception-name> exception; and are raised


using the syntax
raise <exception-name>
45
Exception example

 p40.sql
 SQL> execute insert_odetails(1234, 1111, -5);
– 'Quantity is invalid'
 SQL> execute insert_odetails(2000, 10900, 10);
 SQL> execute insert_odetails(2000, 11001, 10);
– 'PRIMARY KEY VIOLATION'

46
Exercises
 Try all the following triggers:
– trig1.sql; trig2.sql; trig2test.sql; trig3.sql; trig_tables.sql
(SQL script for creating tables for the triggers).
 Try all the following cursors:
– p7.sql; p8.sql (Updatable Cursor); p9.sql (Cursor Variable)
 Try all the following tables:
– p10.sql (Table-based record); p11.sql (Cursor-based
record); p12.sql (Programmer-defined record)
 Try the table: p13.sql

47
Exercises

 Try all the packages


– p18.sql (DBMS_SQL Package -- Executing
non-query SQL)
– p19.sql (DBMS_SQL Package -- Executing
drop/create)
– p20.sql; p21.sql; p22.sql (DBMS_SQL -
Executing Query)
 Try the Exception Handling: p40.sql
48

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy