MC01 Oracle 触发器

You might also like

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 21

触发器

课程目标
• 触发器的组成
• 创建 DML 触发器
• 创建替代触发器
• 创建系统事件触发器
• 创建用户事件触发器
• 重编译触发器
触发器

触发器是一种在发生数据库
事件时自动运行的 PL/SQL 代码块,
在一般情况下它与特定表上的 DML 操
作相关联。注意触发器与数据库中其
他过程的区别,过程或函数都由用户
直接调用,而触发器的执行用户则不
能直接调用。 Oracle 会在相应的事件
发生时,自动调用触发器。
触发器的组成结构

CREATE [OR REPLACE] TRIGGER trigger_name


AFTER | BEFORE | INSTEAD OF
[INSERT] [[OR] UPDATE [[OR] DELETE] [OF column_list]]
ON table_or_view_name
[FOR EACH ROW]
[WHEN (condition)]
BEGIN
pl/sql_block;
END;
触发器的组成结构
• 创建一个触发器,该触发器实现当部门表中的部门编号发
生变化时,员工表中的部门编号也作相应更改。例如当部
门表中部门编号 20 被更改为 80 ,则通过触发器把员工表
中的所有部门编号为 20 也相应更改为 80 。

create or replace trigger dept_update_trigger


after update on DEPT
for each row
begin
update emp set deptno=:NEW.DEPTNO
where deptno=:OLD.deptno;
end;
触发器的组成结构
在前面的触发器例子中,实际包含了 4 个主
要组成部分:
• 触发器名称
create or replace trigger incr_trigger
• 触发条件
before insert on temp_table
for each row
• 触发器限制
when (new.id <=200)
• 触发器主体
begin
end;
:NEW 和 :OLD

• DML 触发器的临时表 :NEW 和 :OLD


当用户对数据进行操作时,系统会产生临时表 :NEW
和 :OLD ,这些临时表仅仅存在与当前的 DML 操作,表
的结构与 DML 操作表的结构一致。
– :NEW
如果 DML 是 INSERT 或 UPDATE 的操作,则产生 :NEW 临时表
,存储的值是 DML 操作插入或更改的新值。
– :OLD
如果 DML 是 DELETE 或 UPDATE 的操作,则产生 :OLD 临时表
,存储的值是 DML 操作删除或更改前的值。

注意:
UPDATE 的操作可以看成 DELETE 和 INSERT 的两次操
作。
:NEW 和 :OLD 仅用在于行级触发器,不适用与语句级
触发器( why ?)
练习
创建触发器,使得当部门被修改,对修改前的
部门数据做备份,备份时要记录操作类型,和
操作时间。
需要先创建备份表 DETP_BAK:
CREATE TABLE DEPT_BAK
AS SELECT * FROM DEPT WHERE 1=2

增加“备份类型”和“备份时间”字段:
alter table DEPT_BAK add (
BAK_TYPE varchar(100),
BAK_TIME TIMESTAMP
)
练习
在 PL/SQL Developer 中打开一个程序窗口(不是 SQL 窗口
, SQL 窗口中看不到编译的错误信息),在窗口中写如下的语
句,并执行:

create or replace trigger bak_dept_trigger


before update on dept
for each row
begin
insert into DEPT_BAK(DEPTNO, DNAME, LOC, BAK_TYPE, BAK_TIME)
values(:OLD.DEPTNO, :OLD.DNAME, :OLD.LOC, 'UPDATE', sysdate);
end;
触发器的类型
Oracle 具有不同类型的触发器,包括:
 DML 触发器 :当对表进行 DML 操作时触发,可以在
DML 操作前或操作后进行触发。如在表或视图上的数
据操作语句,像 INSERT 、 UPDATE 和 DELETE 操作

 DDL 触发器:当 DDL 事件发生时而触发。在对象上的
数据定义语句,如 CREATE 、 ALTER 和 DROP ;
 替代触发器:替代触发器是 Oracle 来用替换所使用
的实际语句而执行的触发器。
 系统触发器:系统触发器就是在 Oracle 数据库系统
的事件中进行触发,如 Oracle 系统的启动与关闭等 .
DML 触发器

• DML 触发器是在针对某个表进行 DML 操作时触发的,创建


DML 触发器语法如下:
create [or replace] trigger 触发器名 触发时间 { before | after
}
触发事件 { insert | delete | update [of column, …] }
on { 表名 | 视图名 }
[for each row]
[ when condition]
begin
pl/sql 语句 ;
end;
语句级触发器和行级触发器
• 语句级触发器
如果在创建触发器时未使用 for each row
子句,则该触发器为语句级触发器,该触发
器在每个数据修改语句执行后只调用一次,
而不管这一操作将影响到多少行。
• 行级触发器
如果在创建触发器时使用 for each row 子
句,则该触发器为行级触发器,当一个 DML
操作影响数据库中的多行数据时,对于每个
数据行,行级触发器均会被触发一次。
替代 (INSTEAD OF) 触发器
与 DML 触发器不同,在定义替代触发器后,用户对
表的 DML 操作将不再被执行,而是执行触发器主体中的操
作。

使用替代触发器的一个常用情形是对视图的操作:
如果一个视图由多个基表进行连接而成的,当这种操
作是同时影响到 2 个基表以上时,视图不允许用户进行
insert 、 update 和 delete 的操作。
如果我们要进行上述的操作,则必须将 DML 操作
定义在替代触发器中分别对各个基表进行操作。
因此,使用 DML 触发器一般是定义在表上,而替代
触发器一般是定义在视图上。
替代 (INSTEAD OF) 触发器
• 创建一个 INSTEAD OF 触发器语法:
create [or replace] trigger 触发器名
instead of
触发事件 { insert | delete | update [of column, …] }
on { 视图名 | 表名? }
[for each row]
[ when condition]
begin
pl/sql 语句 ;
end;
经测试,在 Oracle10G 上不能在表上创建替代触发器。
系统事件触发器
系统事件触发器是指由数据库系统事
件触发的数据库触发器。数据库系统事件
包括如下几种:
• 数据库的启动 (startup)
• 数据库的关闭 (shutdown)
• 数据库服务器的出错 (servererror)
注意:系统事件触发器不是与特定的表或
视图关联。
系统事件触发器定义
• 创建一个系统事件触发器
create [or replace] trigger 触发器名
{ before | after }
{ database_event_list }
on { database | schema }
begin
pl/sql 语句 ;
end;
系统事件触发示例
• 例子:创建一个系统事件触发器,记录系统每次
的启动时间:
create table database_log(op_date timestamp);

create or replace trigger database_startup


after startup
on database
begin
insert into database_log values(sysdate);
end;
用户事件触发器
• 用户事件触发器是指与数据库定义语句 DDL 或
用户登录 / 注销等事件相关的触发器,并且可
以规定触发时间 before 和 after :
create, alter, drop, analyze, audit, notaudit
grant, revoke, rename, truncate
只可以指定触发时间 before 的用户事件 :
logoff
只可以指定触发时间 after 的用户事件 :logon
用户事件触发器

• 例子:创建一个用户事件触发器,记录用户登录系
统的用户名与时间
create table login(who varchar2(20),log
timestamp);

create or replace trigger tr_log


after logon
on schema
begin
insert into login values(user,sysdate);
end;
该触发器记录是否所有用户的登录信息?
ALTER TRIGGER 语句
ALTER TRIGGER 语句用来重新编译、启用或禁用触发
器。如果在触发器内调用了函数或过程,则当这些函数或过程
被删除或修改后,触发器的状态将被标识为无效 INVALID 。
当触发一个无效触发器时, Oracle 将重新编译触发器
代码,如果重新编译时发现错误,这将导致 DML 语句执行失
败。
在 PL/SQL 程序中可以调用 alter trigger 语句,重新编

已经创建的触发器:
alter trigger [schema.] trigger_name compile;
alter trigger 的另外一种用法是禁用和启用触发器 :
alter trigger [schema.] trigger_name disable | enable;
DROP TRIGGER 语句

删除触发器:
DROP TRIGGER 触发器名

You might also like