第 22 课PL/SQL5
1-1-22
教学目标•Trigger•CREATE Trigger•MANAGE Trigger•使用 Trigger
1-1-33
Overview of Triggers
• 触发器类似于函数和过程,它们都是具有声明部分、执行部分和异常处理部分的命名 P L / S Q L 块• 触发器是一个数据库对象,在数据库中以独立对象的身份存储• 触发器是在事件发生时隐式地运行的,并且触发器不能接收参数
1-1-44
Overview of Triggers
• 触发事件可以是对数据库表的 D M L ( I N S E RT 、 U P D AT E 或 D E L E T E )操作或某种视图的操作 ( Vi e w ) 。• Database triggers execute implicitly when an
DML statement (triggering statement) is issued against the associated table, no matter which user is connected
• A trigger can be either a database trigger or an application trigger.
1-1-55
Designing Triggers 须注意• Perform related actions• Use triggers for global operations
1-1-66
ApplicationApplication
SQL> INSERT INTO EMP 2 . . .;
EMP tableEMP tableEMPNO 7838 7698 7369 7788
ENAMEKINGBLAKESMITHSCOTT
JOBPRESIDENTMANAGERCLERKANALYST
SAL50002850 8003000
CHECK_SAL triggerCHECK_SAL trigger
Database Trigger: Example
1-1-77
Creating Triggers 语句的组成CREATE [OR REPLACE ] TRIGGER trigger__name{BEFORE |AFTER | INSTEAD OF}eventON {table_or_view_name}[FOR EACH ROW [WHEN condition ]]trigger_body
1-1-88
Creating Triggers 语句的组成• Trigger timing: BEFORE or AFTER• Triggering event: INSERT or UPDATE
or DELETE• Table name: On table 名• Trigger type: Row or statement
1-1-99
Creating Triggers 语句的组成• When clause: Restricting condition.– 如果在 W H E N 子句中指定 trigger con
dition 的话,则首先对该条件求值。触发器主体只有在该条件为真值时才运行。– W H E N 子句只适用于行级触发器。如果使用该子句的话,触发器体将只对满足由
W H E N 子句说明的条件的行执行。• Trigger body: DECLARE
BEGIN END;
1-1-1010
语句的组成Trigger Timing: When should the trigger fire?• BEFORE: The code in the trigger body
will execute before the triggering DML event.• AFTER: The code in the trigger body will
execute after the triggering DML event.
1-1-1111
语句的组成Trigger Timing: When should the trigger fire?• INSTEAD OF: The code in the trigger
body will execute instead of the the triggering statement. 可以定义在 VIEW 上 .
1-1-1212
语句的组成Triggering Event: What DML operation will cause the trigger to execute?• INSERT• UPDATE • DELETE• Any combination of the above :之间用 or 连接– INSERT OR UPDATE: 在执行 INSERT 或 UP
DATE 时都会触发此 TRIGGER.
1-1-1313
语句的组成Trigger Type:How many times should the trigger body execute when the triggering event takes place?• Statement: The trigger body executes once for
the triggering event. • This is the default.
• Row: The trigger body executes once for each row affected by the triggering event.• 用 FOR EACH ROW 子句指定。
1-1-1414
语句的组成Trigger Body:What action should the trigger perform?• The trigger body is defined with an anonymous
PL/SQL block.[DECLARE]BEGIN[EXCEPTION]END;
1-1-1515
SQL> UPDATE emp 2 SET sal = sal * 1.1 3 WHERE deptno = 30;
Example Example
Statement and Row Triggers
1-1-1616
EMPNOEMPNO
78397839
76987698
77887788
ENAMEENAME
KINGKING
BLAKEBLAKE
SMITHSMITH
DEPTNODEPTNO
3030
3030
3030
BEFORE statement triggerBEFORE statement trigger
BEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row triggerBEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row triggerBEFORE row triggerBEFORE row triggerAFTER row triggerAFTER row trigger
AFTER statement triggerAFTER statement trigger
Firing Sequence of Database Triggers on Multiple Rows
1-1-1717
触发器的触发顺序触发器是在 D M L 语句运行时激发的。下面是执行 D M L 语句的算法步骤:1 ) 如果有语句之前级触发器的话,先运行该触发器。2 ) 对于受语句影响每一行:• a. 如果有行之前级触发器的话,运行该触发器。• b. 执行该语句本身。• c. 如果有行之后级触发器的话,运行该触发器。
3 ) 如果有语句之后级触发器的话,运行该触发器。
1-1-1818
Before Statement Trigger: Example
EXAMPLE:trigger_test.txt
1-1-1919
Creating a Row Trigger
CREATE [OR REPLACE] TRIGGER trigger_nametiming event1 [OR event2 OR event3]ON table_name [REFERENCING OLD AS old | NEW AS new]FOR EACH ROW[WHEN condition]PL/SQL block;
1-1-2020
SQL>CREATE OR REPLACE TRIGGER audit_emp 2 AFTER DELETE OR INSERT OR UPDATE ON emp 3 FOR EACH ROW 4 BEGIN 5 IF DELETING THEN 6 UPDATE audit_table SET del = del + 1 7 WHERE user_name = user AND table_name = 'EMP' 8 AND column_name IS NULL; 9 ELSIF INSERTING THEN 10 UPDATE audit_table SET ins = ins + 1 11 WHERE user_name = user AND table_name = 'EMP' 12 AND column_name IS NULL; 13 ELSIF UPDATING ('SAL') THEN 14 UPDATE audit_table SET upd = upd + 1 15 WHERE user_name = user AND table_name = 'EMP' 16 AND column_name = 'SAL'; 17 ELSE /* The data manipulation operation is a general UPDATE. */ 18 UPDATE audit_table SET upd = upd + 1 19 WHERE user_name = user AND table_name = 'EMP' 20 AND column_name IS NULL; 21 END IF; 22 END; 23 /
After Row Trigger: Example
1-1-2121
行级触发器的相关标识1. 行级触发器是按触发语句所处理的行激发的。在触发器内部,我们可以访问正在处理中的行的数据。2. 这种访问是通过两个相关的标识符:• : o l d 和 : n e w 实现的。3. : new.field 只有在该字段位于触发表中时才是合法的。
1-1-2222
行级触发器的相关标识触发语句I N S E RT (: o l d): 无定义 , 所有字段为空 N U L L (: n e w): 该语句结束时将插入的值U P D AT E (: o l d): 更新前行的原始值(: n e w): 该语句结束时将更新的值D E L E T E (: o l d): 行删除前的原始值(: n e w): 无定义 - 所有字段为空 N U L L
1-1-2323
行级触发器的相关标识引用子句1. 我们可以根据需要使用子句 R E F E R E N C I N
G 来为 :new 和 :old 指定一个不同的名称。2. 该子句可以在触发事件之后, W H E N 子句之前使用,3. 其语法如下:4. REFERENCING [OLD AS :old_name] [NEW AS
:new_name]5. 在触发器体内,我们可以使用 : old_name 和 : ne
w_name 来代替 : old 和 : new 。
1-1-2424
行级触发器的相关标识EXAMPLE:trigger_row.txt
1-1-2525
Differentiating Between Triggers and Stored Procedures
Triggers
Use CREATE TRIGGER
Data dictionary contains source and p-code
Implicitly invoked
COMMIT, SAVEPOINT, ROLLBACK not allowed
Procedure
Use CREATE PROCEDURE
Data dictionary contains source and p-code
Explicitly invoked
COMMIT, SAVEPOINT, ROLLBACK allowed
1-1-2626
ALTER TRIGGER trigger_name DISABLE | ENABLE
Managing TriggersDisable or Re-enable a database triggerDisable or Re-enable a database trigger
ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS
Disable or Re-enable all triggers for a tableDisable or Re-enable all triggers for a table
ALTER TRIGGER trigger_name COMPILE
Recompile a trigger for a tableRecompile a trigger for a table
1-1-2727
Removing Triggers
To remove a trigger from the database, use the DROP TRIGGER syntax:
DROP TRIGGER trigger_name
1-1-2828
Triggers 管理的方法• Rule 1: • Do not change data in the primary key, f
oreign key, or unique key columns of a constraining table (约束表) .
• Rule 2:• Do not read data from a mutating table(变异表) .
1-1-2929
Triggers 管理的方法• 系统对触发器将要访问的表和列有一些限制。为了定义这些限制,有必要来理解什么是变异表( mut
ating table )和约束表 (constraining table).
• 变异表就是当前被 D M L 语句修改的表。对触发器来说,变异表就是触发器在其上进行定义的表• A table is not considered mutating for STATEM
ENT triggers.
1-1-3030
Triggers 管理的方法
• 约束表是一种需要实施引用完整性约束而读入的表 , 即在– FOREIGN KEY(field) REFERENC
ES 参照表 (field)– 如:– FOREIGN KEY(deptno) REFERE
NCES dept_new(deptno);
1-1-3131
Triggering eventTriggering event
Trigger actionTrigger action
SQL> UPDATE emp 2 SET deptno = 20 3 WHERE deptno = 30;
EMP tableEMP tableEMPNO769876547499
ENAMEBLAKEMARTINALLEN
DEPTNO303030
Referential integrityReferential integrity DEPT_new tableDEPT_new tableDNAMEACCOUNTINGRESEARCHSALESOPERATIONS
DEPTNO10203040
Failure ConstrainingConstrainingtabletable
AFTER UPDATEAFTER UPDATErowrow
xxxxxxxxxxxxxxxxxxxxxxxxxxxxvvvvvvvvvvvvvvvvvvvvvvvvvvvvxxxxxxxxxxxxxxxxxxxxxxxxxxxxvvvvvvvvvvvvvvvvvvvvvvvvvvvvxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TriggeredTriggeredtabletable
CASCADE_UPDATESCASCADE_UPDATEStriggertrigger
Changing Data in a Constraining Table
1-1-3232
Constraining Table: Example
CREATE OR REPLACE TRIGGER cascade_updates AFTER UPDATE OF deptno on emp FOR EACH ROW BEGIN UPDATE dept_new SET dept_new.deptno = :new.deptno
WHERE dept_new.deptno = :old.deptno; END;
1-1-3333
Constraining Table: Example
EXAMPLE:constraint_trigger.txt
1-1-3434
Trigger eventTrigger event
SQL> UPDATE emp 2 SET sal = 1500 3 WHERE ename = 'SMITH';
EMP tableEMP tableEMPNO736976987788
ENAMESMITHBLAKESCOTT
SAL150028503000
Failure
Trigged table/Trigged table/mutating tablemutating table
BEFOREBEFOREUPDATEUPDATErowrow
CHECK_SALARYCHECK_SALARYtriggertrigger
Reading Data from a Mutating Table
JOBCLERKMANAGERANALYST
1-1-3535
Mutating Table: Example
EXAMPLE:1. 在 insert ,update 员工 salary 之前,检查新指定的
salary 。如果新指定的 salary 高于所有员工中的最高工资 , 或低于所有员工中的最低工资,则提示错误.
mutating_table.txt
1-1-3636
Trigger 的功能• Security Security – :trigger_test.txt:trigger_test.txt 中的中的 secure_empsecure_emp
• Auditing – :trigger_row txttxt 中的中的 audit_emp_v
alues• Data integrity• Referential integrity• Table replication• Event logging
1-1-3737
小结•Trigger•CREATE Trigger•MANAGE Trigger•使用 Trigger