触发器的基本概念
触发事件
- DML语句事件:执行INSERT、UPDATE、 DELETE等语句时触发的事件
- DDL语句事件:执行CREATE、ALTER、DROP语句等语句时触发的事件
- 数据库事件:执行STARTUP、SHUTDOWN、 LOGON、LOGOFF等操作时触发的事件
- 系统错误:当Oracle数据库系统出现错误时触发的事件
触发时间
- BEFORE:在指定的事件发生之前执行触发器。
- AFTER:在指定的事件发生之后执行触发器
触发级别
- 行触发:对触发事件影响的每一行(如,一条语句更新或删除多条记录)都执行触发器
- 语句触发:对于触发事件只能执行触发器一次
创建触发器
创建语句触发器
CREATE [ OR REPLACE ] TRIGGER 触发器名
[BEFORE | AFTER ] 触发事件 ON 表名 | 视图名
PL/SQL程序体
触发事件可以是INSERT、UPDATE和DELETE等。
表名 | 视图名定义了与触发器相关的表或视图名。
PL/SQL程序体是触发器触发时要执行的程序块
示例:
CREATE OR REPLACE TRIGGER USERMAN.LogUpdateTrigger
AFTER INSERT OR UPDATE OR DELETE
ON USERMAN.Test
DECLARE log_action VARCHAR2(50);
BEGIN
IF INSERTING THEN log_action := 'Insert';
ELSIF UPDATING THEN log_action := 'Update';
ELSIF DELETING THEN log_action := 'Delete';
ELSE DBMS_OUTPUT.PUT_LINE(' ..');
END IF;
INSERT INTO USERMAN.LogTable (log_date, action)
VALUES (SYSDATE, log_action);
END;
/
创建行触发器
仅仅比语句触发器多了FOR EACH ROW
CREATE [ OR REPLACE ] TRIGGER 触发器名
[BEFORE | AFTER ] 触发事件 ON 表名| 视图名
FOR EACH ROW
<PL/SQL程序体>
示例:
CREATE OR REPLACE TRIGGER USERMAN.MyTrigger
AFTER UPDATE ON USERMAN.UserType
FOR EACH ROW
BEGIN
UPDATE USERMAN.Users SET UserType = :new.TypeId
WHERE UserType = :old.TypeId;
END;
/
创建INSTEAD OF触发器
与语句触发器相比,仅仅是用INSTEAD OF代替触发时间
CREATE [ OR REPLACE ] TRIGGER 触发器名
INSTEAD OF 触发事件 ON 表名 | 视图名
PL/SQL程序体
INSTEAD OF 触发器用来代替通常的触发动作,即当对表进行INSERT、UPDATE 或 DELETE 操作时,系统不是直接对表执行这些操作,而是把操作内容交给触发器,让触发器检查所进行的操作是否正确。如正确才进行相应的操作。因此,INSTEAD OF 触发器的动作要早于表的约束处理。
创建LOGON和LOGOFF触发器
LOGON触发器在用户登录数据库时被触发,LOGOFF触发器则在用户注销时被触发。使用这两个触发器可以将用户访问数据库的情况记录在一个日志表中。
CREATE OR REPLACE TRIGGER USERMAN.MyLogonTrigger
AFTER LOGON
ON USERMAN.SCHEMA
BEGIN
INSERT INTO USERMAN.Users_Log VALUES (USER, 'LOGON', SYSDATE);
END;
/
启用和禁用触发器
-
使用ALTER TRIGGER DISABLE语句禁用触发器。
ALTER TRIGGER USERMAN.MyLogoffTrigger DISABLE; -
使用ALTER TRIGGER ENABLE语句可以重新启用触发器。
ALTER TRIGGER USERMAN.MyLogoffTrigger ENABLE; -
如果在一个表上定义了多个触发器,则可以使用ALTER TABLE DISABLE ALL TRIGGERS语句禁用表上的所有触发器。
ALTER TABLE USERMAN.Users DISABLE ALL TRIGGERS; -
使用ALTER TABLE ENABLE ALL TRIGGERS语句可以启用指定表上的所有触发器。
ALTER TABLE USERMAN.Users ENABLE ALL TRIGGERS;
删除触发器
DROP TRIGGER 方案名.触发器名
DROP TRIGGER USERMAN.MyTrigger;