Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1702741
  • 博文数量: 136
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3261
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-22 11:26
文章分类

全部博文(136)

文章存档

2010年(1)

2009年(26)

2008年(109)

我的朋友

分类: Oracle

2008-10-11 15:36:08

1. 判断 DML 的操作类型
 
比如当对表 t2 进行 insert, update, delete 操作时,都需要调用一个触发器。那么在触发器内部如何区分这个 DML 语句的类型呢?可以通过判断该语句是 inserting, updating, 还是 deleting 来判断。
 
SQL> select * from v$version;
 
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
 
SQL> create table t1(dml varchar2(20));
 
表已创建。
 
SQL> create table t2(x number(1));
 
表已创建。
 
SQL> create trigger tri_t2
  2  before insert or update or delete on t2 for each row
  3  begin
  4    if inserting then
  5      insert into t1 values('insert');
  6    elsif updating then
  7      insert into t1 values('update');
  8    elsif deleting then
  9      insert into t1 values('delete');
 10    end if;
 11  end;
 12  /
 
触发器已创建
 
SQL> insert into t2 values(1);
已创建 1 行。
 
SQL> select *from t1;
 
DML
--------------------
insert
 
SQL> update t2 set x = 2;
 
已更新 1 行。
 
SQL> select *from t1;
 
DML
--------------------
insert
update
 
SQL> delete t2;
 
已删除1行。
 
SQL> select * from t1;
 
DML
--------------------
insert
update
delete
 
已选择3行。
 
SQL>
 
2. for each row 关键字
 
创建触发器的语法中有一个可选的关键字:for each row。如果加上它,那么就是行级触发器,对于相关表中的每行进行处理时,都需要对触发器触发一次。如果没有该关键字,那么就是表级触发器,只触发一次。
 
(1)带有each row 的触发器:
 
SQL> truncate table t1;
 
表已截掉。
 
SQL> truncate table t2;
 
表已截掉。
 
SQL> insert into t2 select rownum from user_objects where rownum < 6;
 
已创建5行。
 
SQL> select * from t1;
 
DML
--------------------
insert
insert
insert
insert
insert
 
SQL> update t2 set x = x + 1;
 
已更新5行。
 
SQL> select * from t1;
 
DML
--------------------
insert
insert
insert
insert
insert
update
update
update
update
update
 
已选择10行。
 
SQL> delete t2;
 
已删除5行。
 
SQL> select * from t1;
 
DML
--------------------
insert
insert
insert
insert
insert
update
update
update
update
update
delete
delete
delete
delete
delete
 
已选择15行。
 
(2)不带 each row 的触发器
 
SQL> truncate table t1;
 
表已截掉。
 
SQL> truncate table t2;
 
表已截掉。
 
SQL> create or replace trigger tri_t2
  2  before insert or update or delete on t2
  3  begin
  4    if inserting then
  5      insert into t1 values('insert');
  6    elsif updating then
  7      insert into t1 values('update');
  8    elsif deleting then
  9      insert into t1 values('delete');
 10    end if;
 11  end;
 12  /
 
触发器已创建
 
SQL> insert into t2 select rownum from user_objects where rownum < 6;
 
已创建5行。
 
SQL> select * from t1;
 
DML
--------------------
insert
 
SQL> update t2 set x = x + 1;
 
已更新5行。
 
SQL> select * from t1;
 
DML
--------------------
insert
update
 
SQL> delete t2;
 
已删除5行。
 
SQL> select * from t1;
 
DML
--------------------
insert
update
delete
 
3. 新旧值的获取
 
在触发器中,有时候需要使用相关表修改前/后的值,可以使用 :new 和 :old 来获取。你可以把 :new/:old 看作是相关表的一条记录,通过它们来获取到相关列的数值。它们只能用在行级触发器中。
 
SQL> drop table t1 purge;
 
表已丢弃。
 
SQL> create table t1 (old number(1), new number(1));
 
表已创建。
 
SQL> truncate table t2;
 
表已截掉。
SQL> create or replace trigger tri_t2
  2  before insert or update or delete on t2
  3  begin
  4    insert into t1 values(:old.x, :new.x);
  5  end;
  6  /
create or replace trigger tri_t2
                          *
ERROR 位于第 1 行:
ORA-04082: NEW 或 OLD 引用不允许在表级触发器中
 

SQL> create or replace trigger tri_t2
  2  before insert or update or delete on t2 for each row
  3  begin
  4    insert into t1 values(:old.x, :new.x);
  5  end;
  6  /
 
触发器已创建
 
SQL> insert into t2 values(1);
 
已创建 1 行。
 
SQL> select * from t1;
 
       OLD        NEW
---------- ----------
                    1
 
SQL> update t2 set x = 2;
 
已更新 1 行。
 
SQL> select * from t1;
 
       OLD        NEW
---------- ----------
                    1
         1          2
 
SQL> delete t2;
 
已删除 1 行。
 
SQL> select * from t1;
 
       OLD        NEW
---------- ----------
                    1
         1          2
         2
阅读(4798) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~