DML触发器有三类: 1, insert触发器;2, update触发器;3, delete触发器; 可创建触发器的对象:数据库表,数据库视图,用户模式,数据库实例 创建DML触发器: Create [or replace] trigger [模式.]触发器名 Before| after insert|delete|(update of 列名) On 表名 [for each row] When 条件 PL/SQL块 For each row的意义是:在一次操作表的语句中,每操作成功一行就会触发一次;不写的话,表示是表级触发器,则无论操作多少行,都只触发一次; When条件的出现说明了,在DML操作的时候也许一定会触发触发器,但是触发器不一定会做实际的工作,比如when 后的条件不为真的时候,触发器只是简单地跳过了PL/SQL块; 表级触发器在更新了多行的情况下,只触发了一次; 如果在after update on student后加上For each row的话就成为行级触发器。 :new 与: old:必须是针对行级触发器的,也就是说要使用这两个变量的触发器一定有for each row这两个变量是系统自动提供的数组变量,:new用来记录新插入的值,old用来记录被删除的值;使用insert的时候只有:new里有值;使用delete的时候只有:old里有值;使用update的时候:new和:old里都有值;带有:old变量的行级delete触发器: create or replace trigger tg_deletestudent before delete on student for each row begin dbms_output.put_line('old is: '||:old.stuid); dbms_output.put_line('old name: '||:old.stuname); end; When子句:触发器主题只对满足when所定义条件的那些记录行执行,可以在when子句内部使用new和old记录,不需要用冒号。 混合类型触发器: Inserting,deleting,updating三个谓词可以分别指示当前操作到底是哪个; create or replace trigger hunhetrigger before insert or update or delete on student for each row begin if inserting then dbms_output.put_line('insert le.........'); end if; if deleting then dbms_output.put_line('delete le .......'); end if; end; 插入的时候就自动判断当前动作为插入: SQL> insert into student values(303,'me','f'); insert le......... 删除的时候就自动判断当前动作为删除: SQL> delete from student; delete le ....... 注意,既然触发器内部的主体PL/SQL是语句,那么它同样也可以是插入删除操作而不一定只是dbms_output打印一些信息; 这正是日志表的原理:在用户执行了DML语句的时候触发主体为插入日志表以记录操作轨迹的触发器; 触发器会使得原来的SQL语句速度变慢; 替代触发器:创建在视图上的触发器,就是替代触发器,只能是行级触发器; 为什么要用替代触发器? 假如你有一个视图是基于多个表的字段连接查询得到的;现在如果你想直接对着这个视图insert;那你一定在想,我对视图的插入操作,怎么来反应到组成这个视图的各个表中呢?事实上,除了定义一个触发器来绑定在对视图上的插入动作上外,你没有别的办法通过系统的报错而直接向视图中插入数据;这就是我们用替代触发器的原因;替换的意思实际上是触发器的主体部分把对视图的插入操作转换成详细的对各个表的插入; 变异表:变异表就是当前SQL语句正在修改的表,所以在一个变异表上绑定的触发器不可以使用cout()函数,原因很简单:SQL语句刚刚修改了表,你怎么统计?? 约束表: 维护: Alter trigger …..disenable; 使得触发器不可用; Alter trigger ……enable; 开启触发器; |