触发器
触发器必须由事件触发.
触发事件分为3类:DML事件、DDL事件、数据库事件。
触发器分为4类:DML触发器、DDL触发器、数据库事件触发器、替代触发器。
注:触发器内不能使用commit,rollback,savepoint 语句,也不能直接或间接调用含有上述语句的存储过程和存储函数。
DML触发器
实例1
先创建一个触发事件记录表event_record
createtable event_record(
record_id number(10)primary key,
dml_name varchar2(15),
table_name varchar2(20),
time date,
user_name varchar2(20)
);
创建一个序列squ
createsequence squ incrementby 1 startwith 1 maxvalue999999 nocycle nocache;
创建并编译触发器dml_log
createor replace triggerdml_log
before --在事件操作前触发
insertor update ordelete --触发事件
onemp--触发器定义在emp表上
foreach row --行级触发器
begin
ifinserting then
insert into event_recordvalues(squ.nextval,'INSERT','EMP',sysdate,user);
elsifupdating then
insert into event_recordvalues(squ.nextval,'UPDATE','EMP',sysdate,user);
else
insert into event_recordvalues(squ.nextval,'delete','EMP',sysdate,user);
end if;
end;
现在你对emp表进行DML操作来验证触发器的作用吧!
实例2
创建一个触发器change_sal,只能修改部门10的雇员工资
createor replace triggerchange_sal
before
updateof sal
onemp
foreach row
begin
if:new.deptno!=10 then --注意new和old,它们放在可执行代码中要加:,放在when条件中不用加:。
raise_application_error(-20001,'您不能修改10号部门外的雇员工资!'); --用函数反馈错误信息
end if;
end;
实例3
创建级联删除触发器cascade_delete,当删除dept表中的部门时,级联删除emp表中雇员信息。
createor replace triggercascade_delete
after --在事件操作后触发
delete
ondept
foreach row
begin
deletefrom emp wheredeptno=:old.deptno;
end;
实例4
创建一个语句级触发器oprate_trigger,限定只能emp表进行修改操作,不能对数据库进行插入和删除。
createor replace triggeroprate_trigger
before
updateor delete orinsert
onemp --注意下面一行没有for eachrow ,所以是语句级触发器
begin
if updating then
insert into event_recordvalues(squ.nextval,'UPDATE','EMP',sysdate,user);
else
raise_application_error(-20008,'您不能对emp表进行插入和删除操作!');
end if;
end;
DDL触发器
createor replace triggernocreate_trigger
before
create
onschema --在当前模式
begin
raise_application_error(-20006,'您在当前模式下,不能创建任何对象!');
end;
数据库事件触发器
先创建一个表user_log
createtable user_log(
user_name varchar2(20),
logon_time date,
logoff_time date
);
创建并编译触发器datebase_logon
createor replace triggerdatebase_logon
after
logon
onschema --当前模式
begin
insert into user_logvalues(user,sysdate,'');
end;
创建并编译触发器datebase_logoff
createor replace triggerdatebase_logoff
before
logoff
onschema --当前模式
begin
insert into user_logvalues(user,'',sysdate);
end;
替代触发器
替代触发器只能创建在视图上,用来替代对视图进行的插入、修改和删除操作。
先创建一个视图
createview emp_ename as selectename from emp;
创建并编译触发器change_ename
createor replace triggerchange_ename
insteadof --注意替代触发器的用法
insert
onemp_ename
declare
v_empnoemp.empno%type;
begin --注意里面的程序,当遇到对视图插入时,转化为对表的插入来达到对视图插入的目的(因为empno为表的主键)
selectmax(empno)+1 into v_empnofrom emp;
insertinto emp(empno,ename) values(v_empno,:new.ename);
end;
其他知识(以触发器change_ename为例)
通过user_triggers视图来查看触发器:select * from user_triggers;
使触发器失效:alter triggerchange_ename disable;
使触发器生效:alter triggerchange_ename enable;
删除触发器:drop triggerchange_ename;