Advanced SQL: Triggers
& Assertions
Instructor: Mohamed Eltabakh
meltabakh@cs.wpi.edu
1
Triggers
2
Triggers: Introduction
The application constraints need to be captured inside the database
Some constraints can be captured by:
Primary Keys, Foreign Keys, Unique, Not NULL, and domain constraints
CREATE TABLE Students
(sid: CHAR(20),
name: CHAR(20) NOT NULL,
These constraints are
login: CHAR(10),
age: INTEGER,
defined in CREATE TABLE
gpa: REAL Default 0, or ALTER TABLE
Constraint pk Primary Key (sid),
Constraint u1 Unique (login),
Constraint gpaMax check (gpa <= 4.0) );
3
Triggers: Introduction
Other application constraints are more complex
Need for assertions and triggers
Examples:
Sum of loans taken by a customer does not exceed 100,000
Student cannot take the same course after getting a pass
grade in it
Age field is derived automatically from the Date-of-Birth field
4
Triggers
A procedure that runs automatically when a
certain event occurs in the DBMS
The procedure performs some actions, e.g.,
Check certain values
Fill in some values
Inserts/deletes/updates other records
Check that some business constraints are satisfied
Commit (approve the transaction) or roll back (cancel the
transaction)
5
Trigger Components
Three components
Event: When this event happens, the trigger is activated
Condition (optional): If the condition is true, the trigger
executes, otherwise skipped
Action: The actions performed by the trigger
Semantics
When the Event occurs and Condition is true, execute
the Action
Lets see how to define
these components
6
Trigger: Events
Three event types
Insert
Update
Delete
Two triggering times
Before the event
After the event
Two granularities
Execute for each row
Execute for each statement
7
1) Trigger: Event
Trigger name
Create Trigger <name>
Before|After Insert|Update|Delete ON <tablename> That is the event
Example
Create Trigger ABC Create Trigger XYZ
Before Insert On Students After Update On Students
. .
This trigger is activated when an This trigger is activated when an
insert statement is issued, but update statement is issued and
before the new record is inserted after the update is executed
8
Granularity of Event
A single SQL statement may update, delete, or insert many
records at the same time
E.g., Update student set gpa = gpa x 0.8;
Does the trigger execute for each updated or deleted
record, or once for the entire statement ?
We define such granularity
Create Trigger <name> This is the event
Before| After Insert| Update| Delete
For Each Row | For Each Statement
. This is the granularity
9
Example: Granularity of Event
Create Trigger XYZ
Create Trigger XYZ
After Update ON <tablename>
Before Delete ON <tablename>
For each statement
For each row
.
.
This trigger is activated once (per This trigger is activated before
UPDATE statement) after all deleting each record
records are updated
10
2) Trigger: Condition
This component is optional
Create Trigger <name>
Before| After Insert| Update| Delete On <tableName>
For Each Row | For Each Statement
When <condition> That is the condition
If the employee salary > 150,000 then some actions will be taken
Create Trigger EmpSal
After Insert or Update On Employee
For Each Row
When (new.salary >150,000)
11
3) Trigger: Action
Action depends on what you want to do, e.g.:
Check certain values
Fill in some values
Inserts/deletes/updates other records
Check that some business constraints are satisfied
Commit (approve the transaction) or roll back (cancel the
transaction)
In the action, you may want to reference:
The new values of inserted or updated records (:new)
The old values of deleted or updated records (:old)
12
Trigger: Referencing Values
In the action, you may want to reference:
The new values of inserted or updated records (:new)
The old values of deleted or updated records (:old)
Create Trigger EmpSal
After Insert or Update On Employee Inside When, the new
For Each Row and old should not have :
When (new.salary >150,000)
Trigger Begin
if (:new.salary < 100,000)
body End;
Inside the trigger body, they
should have :
13
Trigger: Referencing Values (Contd)
Insert Event
Has only :new defined
Delete Event
Has only :old defined
Update Event
Has both :new and :old defined
Before triggering (for insert/update)
Can update the values in :new
Changing :old values does not make sense
After triggering
Should not change :new because the event is already done
14
Example 1
If the employee salary increased by more than 10%, make sure the
rank field is not empty and its value has changed, otherwise reject the
update
If the trigger exists, then drop it first
Create or Replace Trigger EmpSal
Before Update On Employee
For Each Row Compare the old and new salaries
Begin
IF (:new.salary > (:old.salary * 1.1)) Then
IF (:new.rank is null or :new.rank = :old.rank) Then
RAISE_APPLICATION_ERROR(-20004, 'rank field not correct');
End IF;
End IF;
End;
/ Make sure to have the / to run the command
15
Example 2
If the employee salary increased by more than 10%, then increment the
rank field by 1.
In the case of Update event only, we can specify which columns
Create or Replace Trigger EmpSal
Before Update Of salary On Employee
For Each Row
Begin
IF (:new.salary > (:old.salary * 1.1)) Then
:new.rank := :old.rank + 1;
End IF;
We changed the new value of rank field
End;
/
The assignment operator has :
16
Example 3: Using Temp Variable
If the newly inserted record in employee has null hireDate field, fill it in
with the current date
Create Trigger EmpDate
Since we need to change values, then it
should be Before event
Before Insert On Employee
For Each Row
Declare Declare section to define variables
temp date;
Begin
Select sysdate into temp from dual; Oracle way to select the current date
IF (:new.hireDate is null) Then
:new.hireDate := temp;
End IF; Updating the new value of
End; hireDate before inserting it
/
17
Example 4: Maintenance of
Derived Attributes
Keep the bonus attribute in Employee table always 3% of the salary
attribute
Create Trigger EmpBonus Indicate two events at the
Before Insert Or Update On Employee same time
For Each Row
Begin
:new.bonus := :new.salary * 0.03;
End; The bonus value is always
/ computed automatically
18
Row-Level vs. Statement-Level
Triggers
Example: Update emp set salary = 1.1 * salary;
Changes many rows (records)
Row-level triggers
Check individual values and can update them
Have access to :new and :old vectors
Statement-level triggers
Do not have access to :new or :old vectors (only for row-level)
Execute once for the entire statement regardless how many records are
affected
Used for verification before or after the statement
19
Example 5: Statement-level
Trigger
Store the count of employees having salary > 100,000 in table R
Indicate three events at the
same time
Create Trigger EmpBonus
After Insert Or Update of salary Or Delete On Employee
For Each Statement
Begin
delete from R;
insert into R(cnt) Select count(*) from employee where salary > 100,000;
End;
/
Delete the existing record in R, and
then insert the new count.
20
Order Of Trigger Firing
Loop over each affected record
Even
Before Trigger Before Trigger t After Trigger After Trigger
(statement-level) (row-level) (row- (row-level) (statement-level)
level)
21
Some Other Operations
Dropping Trigger
SQL> Create Trigger <trigger name>;
If creating trigger with errors
SQL > Show errors;
22
Assertions
23
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
24
Example 1
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 );
25
Example 2
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 );
26
Example 3
Customer city is always not null
Create Assertion CityCheck Check
( NOT EXISTS (
Select *
From customer
Where customer_city is null));
27
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
(Contd)
All assertions can be implemented as triggers (one or more)
Not all triggers can be implemented as assertions
Oracle does not have 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;
Triggers & Assertions
Any Questions
31