30
Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Embed Size (px)

Citation preview

Page 1: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 1

Thursday, March 12, 12:30 – 13:30PM.

MIDTERM

Page 2: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 2

Triggers Chapter 16

Page 3: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Triggers• A trigger is a statement that is executed

automatically by the system as a side effect of a modification to the database.

• To design a trigger mechanism, we must:

– Specify the conditions under which the trigger is to be executed.

– Specify the actions to be taken when the trigger executes.

• Introduced to SQL standard in SQL:1999,

• Supported even earlier using non-standard syntax by most DBMSes.

– Syntax illustrated here is for Oracle 11g.

Page 4: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 4

Objectives

Applied

Create triggers that fire before or after an INSERT, UPDATE, or DELETE statement is executed for a table.

Create triggers that can be used to make views updatable.

Create triggers that fire when DDL events occur.

Create compound triggers.

Use Oracle SQL Developer to work with triggers.

Page 5: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 5

Objectives (continued)

Knowledge

Distinguish between a statement-level trigger and a row-level trigger.

Describe how a trigger can be used to: enforce data consistency, work with sequences, or make a view updatable.

Describe the operation of a compound trigger.

Describe the mutating-table error.

Page 6: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 6

The syntax of the CREATE TRIGGER statement for a table

CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE|AFTER} {DELETE|INSERT|UPDATE [OF col_name1 [, col_name2]...]} [OR {DELETE|INSERT|UPDATE [OF col_name1 [, col_name2]...]}]... ON table_name [FOR EACH ROW [WHEN (trigger_condition)]] pl_sql_block

Page 7: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 7

A trigger that corrects mixed-case state names CREATE OR REPLACE TRIGGER vendors_before_update_state BEFORE INSERT OR UPDATE OF vendor_state ON vendors FOR EACH ROW WHEN (NEW.vendor_state != UPPER(NEW.vendor_state)) BEGIN :NEW.vendor_state := UPPER(:NEW.vendor_state); END; /

Page 8: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 8

An UPDATE statement that fires the trigger UPDATE vendors SET vendor_state = 'wi' WHERE vendor_id = 1;

A SELECT statement that shows the new row SELECT vendor_name, vendor_state FROM vendors WHERE vendor_id = 1;

The result set

Page 9: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 9

A trigger that validates line item amounts CREATE OR REPLACE TRIGGER invoices_before_update_total BEFORE UPDATE OF invoice_total ON invoices FOR EACH ROW DECLARE sum_line_item_amount NUMBER; BEGIN SELECT SUM(line_item_amt) INTO sum_line_item_amount FROM invoice_line_items WHERE invoice_id = :new.invoice_id; IF sum_line_item_amount != :new.invoice_total THEN RAISE_APPLICATION_ERROR(-20001, 'Line item total must match invoice total.'); END IF; END; /

Page 10: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 10

An UPDATE statement that fires the trigger UPDATE invoices SET invoice_total = 600 WHERE invoice_id = 100;

The response from the system ORA-20001: Line item total must match invoice total.

Page 11: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 13

Triggers are commonly used to monitor events occurring in a database.

AFTER Triggers

Page 12: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 14

A statement that creates an audit table CREATE TABLE invoices_audit ( vendor_id NUMBER NOT NULL, invoice_number VARCHAR2(50) NOT NULL, invoice_total NUMBER NOT NULL, action_type VARCHAR2(50) NOT NULL, action_date DATE NOT NULL );

Page 13: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 15

An AFTER trigger that inserts rows into the table CREATE OR REPLACE TRIGGER invoices_after_dml AFTER INSERT OR UPDATE OR DELETE ON invoices FOR EACH ROW BEGIN IF INSERTING THEN INSERT INTO invoices_audit VALUES (:new.vendor_id, :new.invoice_number, :new.invoice_total, 'INSERTED', SYSDATE); ELSIF UPDATING THEN INSERT INTO invoices_audit VALUES (:old.vendor_id, :old.invoice_number, :old.invoice_total, 'UPDATED', SYSDATE); ELSIF DELETING THEN INSERT INTO invoices_audit VALUES (:old.vendor_id, :old.invoice_number, :old.invoice_total, 'DELETED', SYSDATE); END IF; END; /

Page 14: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 16

An INSERT statement that fires the trigger INSERT INTO invoices VALUES (115, 34, 'ZXA-080', '30-AUG-14', 14092.59, 0, 0, 3, '30-SEP-14', NULL);

A DELETE statement that fires the trigger DELETE FROM invoices WHERE invoice_number = 'ZXA-080';

A statement that retrieves the audit table rows SELECT * FROM invoices_deleted;

The result set

Page 15: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 17

Triggers for Views

Recall updateable views?

Page 16: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 18

The syntax of the CREATE TRIGGER statement for a view

CREATE [OR REPLACE] TRIGGER trigger_name INSTEAD OF {DELETE|INSERT|UPDATE [OF col_name1 [, ] col_name2...]} [OR {DELETE|INSERT|UPDATE [OF col_name1 [, ] col_name2...]}]... ON view_name [FOR EACH ROW [WHEN (trigger_condition)]] pl_sql_block

A statement that creates a view CREATE OR REPLACE VIEW ibm_invoices AS SELECT invoice_number, invoice_date, invoice_total FROM invoices WHERE vendor_id = 34;

Page 17: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 19

An INSTEAD OF INSERT trigger for a view CREATE OR REPLACE TRIGGER ibm_invoices_instead_of_insert INSTEAD OF INSERT ON ibm_invoices BEGIN INSERT INTO invoices VALUES (invoice_id_seq.NEXTVAL, 34, :new.invoice_number, :new.invoice_date, :new.invoice_total, 0, 0, 3, :new.invoice_date + 30, NULL); END; /

An statement that succeeds due to the trigger INSERT INTO ibm_invoices VALUES ('ZXA-080', '30-AUG-14', 14092.59);

Page 18: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 20

A statement that retrieves the rows from the view SELECT * FROM ibm_invoices;

The result set

Page 19: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 21

Triggers on DDL Statements

What’s a DDL statement?

Page 20: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 22

The syntax of the CREATE TRIGGER statement for a DDL statement

CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE|AFTER} ddl_event [OR ddl_event]... ON {[schema_name.]SCHEMA|DATABASE} pl_sql_block

DDL events CREATE

ALTER

DROP

GRANT

REVOKE

DDL

Page 21: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 23

A trigger that works with DDL statements CREATE OR REPLACE TRIGGER ap_before_create_drop BEFORE CREATE OR DROP ON ap.SCHEMA BEGIN RAISE_APPLICATION_ERROR(-20001, 'You cannot create or drop an object in the AP schema'); END; /

A CREATE TABLE statement that fires the trigger CREATE TABLE ap.test1 (test_id NUMBER);

The response from the system ORA-20001: You cannot create or drop an object in the AP schema

Page 22: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 24

Disable/Enable Triggers

Why would I want to disable a trigger?

Page 23: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 25

Statements that disable and enable a trigger ALTER TRIGGER ap_before_create DISABLE; CREATE TABLE test1 (test_id NUMBER); DROP TABLE test1; ALTER TRIGGER ap_before_create ENABLE;

Statements that disable and enable all triggers ALTER TABLE invoices DISABLE ALL TRIGGERS; ALTER TABLE invoices ENABLE ALL TRIGGERS;

Page 24: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 26

A statement that renames a trigger ALTER TRIGGER invoices_before_update_total RENAME TO invoices_before_update_inv_tot;

A statement that drops a trigger DROP TRIGGER ap_before_create;

Page 25: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 27

Compound Triggers

Version note Compound triggers were introduced with Oracle Database 11g and

are not available to earlier versions of Oracle Database.

Why do we need another type of trigger?•It solves an well-known problem in Oracle.•Contains code that executes:

• BEFORE the triggering statement executes.• BEFORE the row is modified.• AFTER the row is modified.• AFTER the triggering statement has finished.

Page 26: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 28

A compound trigger CREATE OR REPLACE TRIGGER invoices_compound_update FOR UPDATE OF invoice_total, credit_total ON invoices COMPOUND TRIGGER test_value NUMBER := 1; BEFORE STATEMENT IS BEGIN DBMS_OUTPUT.PUT_LINE('before statement: ' || test_value); END BEFORE STATEMENT; BEFORE EACH ROW IS BEGIN DBMS_OUTPUT.PUT_LINE('before row: ' || test_value); END BEFORE EACH ROW;

Page 27: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 29

A compound trigger (continued) AFTER EACH ROW IS BEGIN DBMS_OUTPUT.PUT_LINE('after row: ' || test_value); END AFTER EACH ROW; AFTER STATEMENT IS BEGIN DBMS_OUTPUT.PUT_LINE('after statement: ' || test_value); END AFTER STATEMENT; END; /

Page 28: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 30

A script that fires the trigger SET SERVEROUTPUT ON; UPDATE invoices SET credit_total = 0 WHERE invoice_id = 100;

The response from the system before statement: 1 before row: 1 after row: 1 after statement: 1

Page 29: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 37

A trigger in SQL Developer

Page 30: Murach’s Oracle SQL and PL/SQL, C16© 2014, Mike Murach & Associates, Inc.Slide 1 Thursday, March 12, 12:30 – 13:30PM. MIDTERM

Murach’s Oracle SQL and PL/SQL, C16 © 2014, Mike Murach & Associates, Inc. Slide 38

A trigger in the Edit window