• No results found

Restricting a Row Trigger

In document Oracle PLSQL - Vol 2 (Page 163-169)

CREATE OR REPLACE TRIGGER derive_commission_pct BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW

WHEN (NEW.job_id = ’SA_REP’) BEGIN

IF INSERTING

THEN :NEW.commission_pct := 0; ELSIF :OLD.commission_pct IS NULL THEN :NEW.commission_pct := 0; ELSE :NEW.commission_pct := :OLD.commission_pct + 0.05; END IF; END; / Example

To restrict the trigger action to those rows that satisfy a certain condition, provide a WHENclause. Create a trigger on the EMPLOYEEStable to calculate an employee’s commission when a row is added to the EMPLOYEEStable, or when an employee’s salary is modified.

The NEWqualifier cannot be prefixed with a colon in the WHENclause because the WHENclause is outside the PL/SQL blocks.

Introduction to Oracle9i: PL/SQL 16-22

16-22 Copyright © Oracle Corporation, 2001. All rights reserved.

INSTEAD OF

Triggers

Application

INSERT INTO my_view . . .;

MY_VIEW

INSTEAD OF

Trigger

INSERT

TABLE1

UPDATE

TABLE2

INSTEAD OFTriggers

Use INSTEAD OFtriggers to modify data in which the DML statement has been issued against an inherently nonupdatable view. These triggers are called INSTEAD OFtriggers, because unlike other triggers, the Oracle server fires the trigger instead of executing the triggering statement. This trigger is used to perform an INSERT, UPDATE, or DELETEoperation directly on the underlying tables.

You can write INSERT, UPDATE, or DELETEstatements against a view, and the INSTEAD OFtrigger works invisibly in the background to make the right actions take place.

Why Use INSTEAD OFTriggers?

A view cannot be modified by normal DML statements if the view query contains set operators, group functions, clauses such as GROUP BY, CONNECT BY, START, the DISTINCToperator, or joins. For example, if a view consists of more than one table, an insert to the view may entail an insertion into one table and an update to another. So, you write an INSTEAD OFtrigger that fires when you write an insert against the view. Instead of the original insertion, the trigger body executes, which results in an insertion of data into one table and an update to another table.

Note: If a view is inherently updatable and has INSTEAD OFtriggers, the triggers take precedence.

INSTEAD OFtriggers are row triggers.

The CHECKoption for views is not enforced when insertions or updates to the view are performed by using INSTEAD OFtriggers. The INSTEAD OFtrigger body must enforce the check.

16-23 Copyright © Oracle Corporation, 2001. All rights reserved.

Creating an INSTEAD OF

Trigger

CREATE [OR REPLACE] TRIGGER

trigger_name

INSTEAD OF

event1

[OR

event2

OR

event3

]

ON

view_name

[REFERENCING OLD AS

old |

NEW AS

new

] [FOR EACH ROW]

trigger_body

Syntax:

Syntax for Creating an INSTEAD OFTrigger

trigger_name Is the name of the trigger.

INSTEAD OF Indicates that the trigger belongs to a view

event Identifies the data manipulation operation that causes the trigger to fire:

INSERT

UPDATE [OF column] DELETE

view_name Indicates the view associated with trigger

Introduction to Oracle9i: PL/SQL 16-24 Creating an INSTEAD OFTrigger

Example:

The following example creates two new tables, NEW_EMPSand NEW_DEPTS, based on the

EMPLOYEESand DEPARTMENTStables respectively. It also creates a view EMP_DETAILSfrom the

EMPLOYEESand DEPARTMENTStables. The example also creates an INSTEAD OFtrigger,

NEW_EMP_DEPT. When a row is inserted into the EMP_DETAILSview, instead of inserting the row directly into the view, rows are added into the NEW_EMPSand NEW_DEPTStables, based on the data in the INSERTstatement. Similarly, when a row is modified or deleted through the EMP_DETAILSview, corresponding rows in the NEW_EMPSand NEW_DEPTStables are affected.

CREATE TABLE new_emps AS

SELECT employee_id, last_name, salary, department_id, email, job_id, hire_date

FROM employees;

CREATE TABLE new_depts AS

SELECT d.department_id, d.department_name, d.location_id, sum(e.salary) tot_dept_sal

FROM employees e, departments d

WHERE e.department_id = d.department_id

GROUP BY d.department_id, d.department_name, d.location_id; CREATE VIEW emp_details AS

SELECT e.employee_id, e.last_name, e.salary, e.department_id, e.email, e.job_id, d.department_name, d.location_id FROM employees e, departments d

WHERE e.department_id = d.department_id; CREATE OR REPLACE TRIGGER new_emp_dept

INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_details FOR EACH ROW

BEGIN

IF INSERTING THEN INSERT INTO new_emps

VALUES (:NEW.employee_id, :NEW.last_name, :NEW.salary,

:NEW.department_id, :NEW.email, :New.job_id, SYSDATE); UPDATE new_depts

SET tot_dept_sal = tot_dept_sal + :NEW.salary WHERE department_id = :NEW.department_id; ELSIF DELETING THEN

DELETE FROM new_emps

WHERE employee_id = :OLD.employee_id; UPDATE new_depts

SET tot_dept_sal = tot_dept_sal - :OLD.salary WHERE department_id = :OLD.department_id;

Creating an INSTEAD OFTrigger (continued) Example:

ELSIF UPDATING (’salary’) THEN

UPDATE new_emps

SET salary = :NEW.salary

WHERE employee_id = :OLD.employee_id; UPDATE new_depts

SET tot_dept_sal = tot_dept_sal + (:NEW.salary - :OLD.salary) WHERE department_id = :OLD.department_id;

ELSIF UPDATING (’department_id’) THEN

UPDATE new_emps

SET department_id = :NEW.department_id WHERE employee_id = :OLD.employee_id; UPDATE new_depts

SET tot_dept_sal = tot_dept_sal - :OLD.salary WHERE department_id = :OLD.department_id; UPDATE new_depts

SET tot_dept_sal = tot_dept_sal + :NEW.salary WHERE department_id = :NEW.department_id; END IF;

END; /

Introduction to Oracle9i: PL/SQL 16-26

16-26 Copyright © Oracle Corporation, 2001. All rights reserved.

Creating an INSTEAD OF

Trigger

INSERT INTO emp_details(employee_id, ... )

VALUES(9001,’ABBOTT’,3000,10,’abbott.mail.com’,’HR_MAN’);

INSERTinto EMP_DETAILSthat is based on EMPLOYEESand

DEPARTMENTStables INSTEAD OF INSERTinto EMP_DETAILS INSERTinto NEW_EMPS UPDATE NEW_DEPTS

Creating an INSTEAD OFTrigger

You can create an INSTEAD OFtrigger in order to maintain the base tables on which a view is based. Assume that an employee name will be inserted using the view. Create a trigger that results in the appropriate INSERTand UPDATEto the base tables.

16-27 Copyright © Oracle Corporation, 2001. All rights reserved.

Differentiating between Database Triggers

In document Oracle PLSQL - Vol 2 (Page 163-169)

Related documents