1、触发器是指存在数据库中,被隐含执行的存储过程,可以支持dml触发器,
还支持基于系统事件[启动数据库,关闭数据库,登录]和ddl操作建立触发器
----------------------
--触发器分类
----------------------
1、dml触发器 - insert、delete、update
2、ddl触发器 - create table|view ..、drop ..
----------------------
--语法介绍
----------------------
create[or replace] trigger trigger_name
{before|after}
{insert|delete|update[of column[,column ....]]}
on[schema.]table_name
[for each row]
[when condition]
begin
tigger_body;
end;
------------------------------------------------
--dml触发器 - insert、delete、update
------------------------------------------------
--案例
1、当插入数据时,就提示添加记录信息
create or replace trigger mytrigger
after insert on scott.emp
begin
dbms_output.put_line('添加一条记录');
end;
insert into emp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
values(7945,'jiji','zhonguo',7566,to_date('1980/12/17', 'yyyy/mm/dd'), 20000,1000,20);
2、在某张表修改多条数据的时候,提示 修改数据
create or replace trigger mytrigger
after update on scott.emp
begin
dbms_output.put_line('修改了数据');
end;
3、--禁止工作人员在休息日改变员工信息
开发人员可以建立before语句触发器,从而实现数据的安全
create or replace trigger mytrigger
before delete on scott.emp
begin
if to_char(sysdate, 'day') in('星期日', '星期六', '星期五') then
--dbms_output.put_line('对不起,休息日不能删除表');
RAISE_APPLICATION_ERROR('-20001', '对不起,休息日不能删除员工'); --自定义错误
end if;
end;
--特别说明
①、RAISE_APPLICATION_ERROR这个过程,是oracle提供的,可以传入两个参数
第一个:自定义的错误号 -20000~-20999
第二个:提示信息
4、--dml联合使用
create or replace trigger mytrigger
before insert or update or delete on scott.emp
begin
case
when inserting then
RAISE_APPLICATION_ERROR(-20002, '请不要添加');
when updating then
RAISE_APPLICATION_ERROR(-20003, '请不要修改');
when deleting then
RAISE_APPLICATION_ERROR(-20004, '请不要删除');
end case;
end;
-----------------------
5、使用 :old 和 :new
-----------------------
问题:当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、后列的值
-- :new 修饰符访问操作完成后列的值
-- :old 修饰符访问操作完成前列的值
特性 insert update delete
old NULL 有效 有效
new 有效 有效 NULL
--案例
1、在修改emp表 雇员的薪水时,显示雇员工资修改前和修改后的值
2、如何确保在修改员工工资不能低于原有工资
create or replace trigger mytrigger
before update on scott.emp
for each row
begin
if :new.sal<:old.sal then
RAISE_APPLICATION_ERROR(-20005, '工资不能低于原有工资');
else
dbms_output.put_line('原有工资:'||:old.sal||'现在工资:'||:new.sal);
end if;
end;
update emp set sal=3 where empno=7934;
update emp set sal=300 where empno=7934;
6、编写一个触发器,保证当用户在删除一张表记录的时候
自动把删除的记录备份到另一张表中
create table emp_bak as select * from emp;
create or replace trigger mytrigger
before delete on scott.emp
for each row
begin
insert into emp_bak(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
values(:old.EMPNO,:old.ENAME,:old.JOB,:old.MGR,:old.HIREDATE,:old.SAL,:old.COMM,:old.DEPTNO);
end;
------------------------------------------------
--ddl触发器 - create table|view ..、drop ..
------------------------------------------------
①为了记录系统所发生的ddl事件,应该建立一张表[ddl_event]用来存储相关信息
②注意需要使用system用户登录conn system/manager as sysdba;
--语法
create or replace trigger 触发器名
after ddl 方案名.schema --如:scott.schema
begin
执行语句
end;
--案例
create table ddl_table(
event varchar2(64), --事件名
username varchar2(64), --用户名
ddl_time date --时间
);
--创建触发器 可以记录某个用户进行的ddl操作
create or replace trigger ddl_triiger
after ddl on scott.schema
begin
insert into ddl_table --插入 事件名、当前用户、当前时间
values(ora_sysevent, ora_login_user, sysdate);
end;
---------------------------------------
--系统触发器
---------------------------------------
--语法
create or replace trigger 触发器名
after[before] logon[logoff] on database
begin
执行语句
end;
注意事项:
①需要建立在sys|system上
②由系统管理员来完成
--常用属性函数
ora_client_ip_address 返回客户端的ip
ora_database_name 返回数据库名
ora_login_user 返回登录用户名
ora_sysevent 返回触发触发器的系统事件名
ora_des_encrypted_password 返回用户des(md5)加密后的密码
--创建表,用于保存用户登录或者退出的情况
create table log_table(
username varchar2(20), --登录名
logon_time date, --登录时间
logoff_time date, --退出时间
address varchar2(20) --登录地址
);
1、--登录触发器
create or replace trigger logon_trigger
after logon on database
begin
insert into log_table(username,logon_time,address)
values(ora_login_user, sysdate, ora_client_ip_address);
end;
2、--退出触发器
create or replace trigger logoff_trigger
before logoff on database
begin
insert into log_table(username,logoff_time,address)
values(ora_login_user, sysdate, ora_client_ip_address);
end;
---------------------------------------
--管理触发器
---------------------------------------
1、禁止触发器
是指让触发器临时失效
alter trigger 触发器名 disable;
2、激活触发器
alter trigger 触发器名 enable;
3、禁止或是激活表的所有触发器
alter table emp disable all triggers;(9i)
alter table emp enable all triggers;(9i)
4、删除触发器
drop trigger 触发器名