1 / 21

Triggers

Triggers. The different types of integrity constraints discussed so far provide a declarative mechanism to associate “ simple ” conditions with a table such as a primary key, foreign keys or domain constraints.

Download Presentation

Triggers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Triggers • The different types of integrity constraints discussed so far provide a declarative mechanism to associate “simple” conditions with a table such as a primary key, foreign keys or domain constraints. • Complex constraints that refer to several tables and attributes cannot be specified within table definitions. • Triggers, in contrast, provide a procedural technique to specify and maintain integrity constraints. • A trigger essentially is a stored procedure. • Such a procedure is associated with a table and is automatically called by the database system whenever a certain modification (event) occurs on that table. • Modifications on a table may include insert, update, and delete operations

  2. Row vs. Statement Triggers • A trigger can be invoked (by the DBMS) before or after the triggering event. • There are two types of triggers: • a row level triggerand • a statement level trigger. • A row level trigger is defined using the clause FOR EACH ROW. If this clause is not given, the trigger is assumed to be a statement trigger. • A row trigger executes once for each row after (or before) the event. • In contrast, a statement trigger is executed once after (or before) the event, independent of how many rows are affected by the event.

  3. Row Triggers • Only with a row trigger it is possible to access the attribute values of a tuple before and after the modification • This is because the trigger is executed once for each tuple. • For an update trigger, the old attribute value can be accessed using :old.<column> • and the new attribute value can be accessed using :new.<column> • For an insert trigger, only :new.<column> can be used. • For a delete trigger only :old.<column> can be used. • In a row trigger thus it is possible to specify comparisons between old and new attribute values in e.g., if :old.sal != :new.sal then . . .

  4. Example • Let’s create the following two tables: CREATE TABLE T1 ( a INTEGER, b CHAR(10) ); CREATE TABLE T2 ( c CHAR(10), d INTEGER ); • We create a trigger that may insert a tuple into T2 when a tuple is inserted into T1. Specifically, the trigger checks whether the new tuple has a first component 10 or less, and if so inserts the reverse tuple into T2: CREATE OR REPLACE TRIGGER trig1 AFTER INSERT ON T1 FOR EACH ROW WHEN (new.a <= 10) BEGIN INSERT INTO T2 VALUES(:new.b, :new.a); END trig1; / • Notice that we end the CREATE TRIGGER statement with a /, as for all PL/SQL statements in general. • This only creates the trigger; it does not execute the trigger. Only a triggering event, such as an insertion into T1 in this example, causes the trigger to execute. No colon ‘:’ here! Try now: insert into T1 values(8, 'Uvic'); The tuple ('Uvic',8) is automatically inserted into T2.

  5. Trigger Syntax • Below is the syntax for creating a trigger in Oracle (which differs slightly from standard SQL syntax): CREATE [OR REPLACE] TRIGGER <trigger_name> {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <table_name> [FOR EACH ROW [WHEN (<trigger_condition>)]] <trigger_body> • You may specify up to three triggering events using the keyword OR. Here are some examples: ... INSERT ON R ... ... INSERT OR DELETE OR UPDATE ON R ...

  6. Trigger Syntax (Cont’d) • If FOR EACH ROW option is specified, the trigger is row-level; otherwise, the trigger is statement-level. • A trigger restriction can be specified in the WHEN clause, enclosed by parentheses. • The trigger restriction is an SQL condition that must be satisfied in order for Oracle to fire the trigger. • <trigger_body> is a PL/SQL block, rather than sequence of SQL statements.

  7. Restrictions • The restrictions on <trigger_body> include: • You cannot modify the same relation whose modification is the event triggering the trigger. • You cannot modify a relation connected to the triggering relation by another constraint such as a foreign-key constraint.

  8. Miscellaneous about Triggers • Displaying Trigger Definition Errors • As for PL/SQL procedures, if you get a message Warning: Trigger created with compilation errors. you can see the error messages by typing • SHOW ERRORS TRIGGER <trigger_name>; • Alternatively, you can type, SHOW ERRORS to see the most recent compilation error. • Note that the reported line numbers where the errors occur are not accurate. • Viewing Defined Triggers • To view a list of all defined triggers, use: SELECT trigger_name FROM user_triggers; • For more details on a particular trigger (example): SELECT trigger_type, triggering_event, table_name, referencing_names, trigger_body FROM user_triggers WHERE trigger_name = 'TRIG1'; Has to be uppercase.

  9. Miscellaneous (Cont’d) • Dropping Triggers drop trigger <trigger_name>; • Disabling Triggers • To disable or enable a trigger: alter trigger <trigger_name> {disable|enable};

  10. Aborting Triggers with Errors • Triggers can often be used to enforce constraints. The WHEN clause or body of the trigger can check for the violation of certain conditions and signal an error accordingly using the Oracle built-in function RAISE_APPLICATION_ERROR. • The action that activated the trigger (insert, update, or delete) would be aborted. For example, the following trigger enforces the constraint Person.age >= 0: CREATE TABLE Person (age INT); CREATE TRIGGER PersonCheckAge AFTER INSERT OR UPDATE OF age ON Person FOR EACH ROW BEGIN IF (:new.age < 0) THEN RAISE_APPLICATION_ERROR(-20000, 'no negative age allowed'); END IF; END; /

  11. Aborting Triggers with Errors (Cont’d) • If we attempted to execute the insertion: INSERT INTO Person VALUES (-3); we would get the error message: ERROR at line 1: ORA-20000: no negative age allowed ORA-06512: at "MYNAME.PERSONCHECKAGE", line 3 ORA-04088: error during execution of trigger 'MYNAME.PERSONCHECKAGE' and nothing would be inserted. In general, the effects of both the trigger and the triggering statement are rolled back.

  12. Mutating Table Errors • Sometimes you may find that Oracle reports a "mutating table error" when your trigger executes. This happens when the trigger is querying or modifying a "mutating table", which is: • either the table whose modification activated the trigger, or • a table that might need to be updated because of a foreign key constraint with a CASCADE policy. • To avoid mutating table errors: • A row-level trigger must not query or modify a mutating table. (Of course, NEW and OLD still can be accessed by the trigger.) • A statement-level trigger must not query or modify a mutating table if the trigger is fired as the result of a CASCADE delete.

  13. A table and some data CREATE TABLE emp ( empno INT, ename VARCHAR(30), deptno INT ); INSERT INTO emp VALUES (7900, 'JAMES', 40); INSERT INTO emp VALUES (7902, 'FORD', 40); INSERT INTO emp VALUES (7934, 'MILLER', 40);

  14. Before Statement-Level Trigger CREATE OR REPLACE TRIGGER emp_alert_trig BEFORE INSERT ON emp BEGIN DBMS_OUTPUT.PUT_LINE( 'New employees are about to be added'); END; / Don’t forget: SET SERVEROUTPUT ON

  15. Inserting • The following INSERT is constructed so that several new rows are inserted upon a single execution of the command. • For each row that has an employee id between 7900 and 7999, a new row is inserted with an employee id incremented by 1000. INSERT INTO emp (empno, ename, deptno) SELECT empno + 1000, ename, 40 FROM emp WHERE empno BETWEEN 7900 AND 7999; New employees are about to be added

  16. Result SELECT empno, ename, deptno FROM emp WHERE empno BETWEEN 8900 AND 8999; EMPNO ENAME DEPTNO ---------- ---------- ---------- 8900 JAMES 40 8902 FORD 40 8934 MILLER 40

  17. After Statement-Level Trigger • Whenever an insert, update, or delete operation occurs on the emp table, a row is added to the empauditlog table recording the date, user, and action. • First let’s create the empauditlog table: CREATE TABLE empauditlog ( audit_date DATE, audit_user VARCHAR2(20), audit_desc VARCHAR2(20) );

  18. Now the trigger CREATE OR REPLACE TRIGGER emp_audit_trig AFTER INSERT OR UPDATE OR DELETE ON emp DECLARE v_action VARCHAR2(20); BEGIN IF INSERTING THEN v_action := 'Added employee(s)'; ELSIF UPDATING THEN v_action := 'Updated employee(s)'; ELSIF DELETING THEN v_action := 'Deleted employee(s)'; END IF; INSERT INTO empauditlog VALUES (SYSDATE, USER, v_action); END; /

  19. Let’s trigger it… INSERT INTO emp VALUES (9001,'SMITH',50); INSERT INTO emp VALUES (9002,'JONES',50); UPDATE emp SET ename = 'SMITH BROWN' WHERE empno=9001; DELETE FROM emp WHERE empno IN (9001, 9002); SELECT TO_CHAR(AUDIT_DATE,'DD-MON-YY HH24:MI:SS') AS "AUDIT DATE", audit_user, audit_desc FROM empauditlog ORDER BY 1 ASC; AUDIT DATE AUDIT_USER AUDIT_DESC ------------------ -------------------- -------------------- 31-OCT-06 11:11:30 THOMO Added employee(s) 31-OCT-06 11:11:30 THOMO Deleted employee(s) 31-OCT-06 11:11:30 THOMO Updated employee(s) 31-OCT-06 11:11:30 THOMO Added employee(s)

  20. Before Row-Level Trigger ALTER TABLE emp ADD Sal INT; ALTER TABLE emp ADD Comm INT; • The following is a before row-level trigger that calculates the commission of every new employee belonging to department 30 that is inserted into the emp table. CREATE OR REPLACE TRIGGER emp_comm_trig BEFORE INSERT ON emp FOR EACH ROW BEGIN IF :NEW.deptno = 30 THEN :NEW.comm := :NEW.sal * .4; END IF; END; /

  21. Let’s trigger INSERT INTO emp VALUES (9005,'ROBERS',30, 3000,NULL); INSERT INTO emp VALUES (9006,'ALLEN',30, 4500,NULL); SELECT * FROM emp WHERE empno IN (9005, 9006); EMPNO ENAME DEPTNO SAL COMM ----------------------------------- 9005 ROBERS 30 3000 1200 9006 ALLEN 30 4500 1800

More Related