Oracle触发器开发与设计

一、 什么是触发器?
数据库触发器是一个存储的PL/SQL程序块,它与一个基表联系,当在表上执行特定的数据库维护(插入、删除、更新这三种操作)时,隐含地执行一个PL/SQL程序块。

二、触发器的作用:
 。防止非法的数据库操纵、维护数据库安全
 。对数据库的操作进行审计,存储历史数据
 。完成数据库初始化处理
 。控制数据库的数据完整性
 。进行相关数据的修改
 。完成数据复制
 。自动完成数据库统计计算
 。限制数据库操作的时间、权限等,控制实体的安全性
 
三、触发器的组成:
1、触发时间:触发器事件的时间次序(before, afer)[2]

2、触发事件:什么SQL语句会引起触发器触发(Insert, delete, update)[3]

3、触发子体:触发器触发时要执行的操作(一个完整的PL/SQL程序)

4、触发类型:触发器被执行的次数(语句级、行级)[2] //语句级只执行一次,行级会执行多次。

[*]一个表上最多可以创建12个不同类型的触发器:3*2*2 = 12

四、创建触发器注意事项:
1、在触发器中可以调用存储过程、包;在存储过程中不得调用触发器。

2、在触发器中不得使用commit, rollback, savepoint语句。

3、在触发器中不得间接调用含有commit, rollback, savepoint的语句的存储过程及函数。

五、创建语句级触发器:
语句级触发器: 请参考PowerPoint教程:存储过程1.ppt[Page19] 该触发器在数据库操作时只执行一次。
说明:
 。update中的of是可选项,用于指定语句要修改的列
 。要创建的触发器已经存在时,使用replace选项

//例1:before型触发器:
Create or replace trigger DelEmp
  before delete on emp
  Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18)
   then dbms_output.put_line('现在是非工作时间,请退出!!!');
   end if;
  End;

[触发器数据字典]
SQL> select table_owner, table_name,trigger_body from user_triggers where trigger_name='DELEMP';

//例2:After型触发器:
Create or replace trigger InsertEmp
after insert on emp     // 如果是before,就会比after的结果少一名。
Declare
 v_empcount number(7);
Begin
 select count(*) into v_empcount from emp;
 dbms_output.put_line('目前员工总数已达到:'|| v_empcount|| '名。');
End;


//例3:多个触发条件
Create or replace trigger ChangeEmp
before delete or insert or update on emp
Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between 8 and 18)
   then dbms_output.put_line('现在是非工作时间,请不要修改数据!!!');
   end if;
End;

// 更完善的写法:
Create or replace trigger ChangeEmp
  before delete or insert or update  on emp
  Begin
   if (DELETING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('现在是非工作时间,不要删除数据!');

   elsif (UPDATING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8 and 18))
   then dbms_output.put_line('现在是非工作时间,不要更新数据!');

   elsif (INSERTING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('现在是非工作时间,不要插入数据!');

   end if;
  End;

六、创建行级触发器:
等级触发器:增加选项for each row, 使触发器在每一行上触发。

1、创建行级触发器注意事项:
(1) 在行级触发器中,在列名前增加old表示该列修改前值,增加new表示该列修改后值。
(2) 在PL/SQL中引用时,前边增加冒号。
 
[例4: 行级触发器] //必须是对所有的行进行操作才行。
Create or Replace trigger UpdateEmp
Before update on emp
for each row
Begin
 dbms_output.put_line(:old.sal||'--------->'||:new.sal);
End;

[例5:保存历史数据,这种使用方法很重要,用来保存关键表的历史数据]
CReate or Replace trigger ChangeEmp
Before update or delete on emp
for each row
Begin
 Insert into oldemp(empno, ename,job,hiredate,sal)
 values(:old.empno,:old.ename,:old.job,sysdate,:old.sal);
End;

SQL> create table oldemp
 as select empno, ename,job,hiredate,sal from emp where 1>2;

[例6:修改外键]
Create or Replace trigger UpdateDept
after update on dept
for each row
Begin
 update emp
  set emp.deptno = :new.deptno
  where emp.deptno = :old.deptno;
End;

[例7:删除外键、删除相关数据]
Create or Replace trigger DeleteDept
before delete on dept
for each row
Begin
 delete from emp where deptno = :old.empno;
End;

七、触发器管理
1、使触发器失效:
SQL> alter trigger 触发器名称 disable;  // 失效
SQL> Alter Trigger 触发器名称 enable;  // 生效

SQL> Alter table 表名 DISABLE all triggers; // 一个表上的所有触发器失效
SQL> Alter table 表名 ENABLE all triggers; // 使一个表上的所有触发器生效

SQL> Drop Trigger 触发器名;  // 删除触发器;

转载于:https://www.cnblogs.com/straw808/archive/2007/09/19/897933.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值