oracle触发器

/*
语句触发器
*/
--before触发器
create or replace trigger tr_sec_emp
before insert or update or delete on emp
begin
if to_char(sysdate,'DY','nls_date_language=AMERICAN')
in('SAT','SUN') THEN
raise_application_error(-20001,'不能在休息日改变库员号');
end if;
end ;
--使用条件谓词(insert or update or delete)
create or replace trigger t_sec_emp
before insert or update or delete on emp
begin
if to_char(sysdate,'DY','nls_date_language=AMERICAN')
in('SAT','SUN') THEN
case
when inserting then
raise_application_error(-20001,'不能在休息日增加雇员');
when updating then
raise_application_error(-20001,'不能在休息日更改雇员');
when deleting then
raise_application_error(-20001,'不能在休息日删除雇员');
end case;
end if;

end;

--after触发器
create table audit_table(
name varchar2(20),ins int,upd int,del int,starttime date,endtime date
)
/
create or replace trigger tr_audit_emp
after insert or update or delete on emp
declare
v_temp int;
begin
select count(*) into v_temp from audit_table
where name='emp';
if v_temp=0 then
insert into audit_table values('emp',0,0,0,sysdate,null);
end if;
case
when inserting then
update audit_table set ins=ins+1 ,endtime=sysdate where name='emp';
when updating then
update audit_table set upd=upd+1 ,endtime=sysdate where name='emp';
when deleting then
update audit_table set del=del+1 ,endtime=sysdate where name='emp';
end case;
end;


/*
行触发器
*/

--before行触发器
create or replace trigger tr_emp_sal
before update of sal on emp
for each row
begin
IF :new.sal<:old.sal then
raise_application_error(-20010,'工资只上涨不下降');
END IF;
end;

--after

create table audit_emp_change(
name varchar2(32),
oldsal number,
newsal number,
time date
)
/

create or replace trigger tr_sal_change
after update of sal on emp
for each row
declare v_temp int;
begin
select count(*) into v_temp from audit_emp_change where name=:old.ename;
if v_temp=0 then
insert into audit_emp_change(name,oldsal,newsal,time) values(:old.ename,:old.sal,:new.sal,sysdate);
else
update audit_emp_change set oldsal=:old.sal ,newsal=:new.sal ,time=sysdate where name=:old.ename;

end if;
end;

--限制行触发器
create or replace trigger tr_sal_change
after update of sal on emp
for each row
when (old.job='SALESMAN')
declare v_temp int;
begin
select count(*) into v_temp from audit_emp_change where name=:old.ename;
if v_temp=0 then
insert into audit_emp_change(name,oldsal,newsal,time) values(:old.ename,:old.sal,:new.sal,sysdate);
else
update audit_emp_change set oldsal=:old.sal ,newsal=:new.sal ,time=sysdate where name=:old.ename;

end if;

end;

/*
使用DML触发器
*/
--1 控制数据安全
--一般授权
grant select ,insert,update ,delete on emp to SMITH;
--
create or replace trigger tr_emp_time
before update or delete or insert on emp
begin

if to_char(sysdate,'HH24') not between '9' and '17' then
raise_application_error(-20101,'非工作时间');
end if;
end;

--2实现数据审计
--字典审计
audit update,delete,insert on emp by access;

--触发器审计
create or replace trigger tr_sal_change
after update of sal on emp
for each row
declare v_temp int;
begin
select count(*) into v_temp from audit_emp_change where name=:old.ename;
if v_temp=0 then
insert into audit_emp_change(name,oldsal,newsal,time) values(:old.ename,:old.sal,:new.sal,sysdate);
else
update audit_emp_change set oldsal=:old.sal ,newsal=:new.sal ,time=sysdate where name=:old.ename;

end if;
end;

--3 实现数据完整性
--约束
alter table emp add constraint ch_sal
check (sal>=800)
--
create or replace trigger tr_check_sal
before update of sal on emp
for each row
when (new.sal<old.sal or new.sal>1.2*old.sal)

begin
raise_application_error(-20931,'工资只升不降,并且升幅不能超过20%');
end;
--4 实现参照完整性
--约束
alter table emp add constraint fk_deptno
foreign key (deptno) references dept(deptno)
on delete cascade;
--触发器实现更新完整性
create or replace trigger tr_update_cascade
after update of deptno on dept
for each row
begin
update emp set deptno=:new.deptno where deptno=:old.deptno;
end;
/*
instead-of 触发器
*/
create or replace view dept_emp as
select a.deptno,a.dname,b.empno,b.ename from dept a,emp b
where a.deptno=b.deptno;
/
create or replace trigger tr_instead_of_dept_emp
instead of insert on dept_emp
for each row
declare v_temp int;
begin
select count(*) into v_temp from dept where deptno=:new.deptno;
if v_temp=0 then
insert into dept(deptno,dname) values(:new.deptno,:new.dname);
end if;
select count(*) into v_temp from emp where empno=:new.empno;
if v_temp=0 then
insert into emp(empno,ename,deptno) values(:new.empno,:new.ename,:new.deptno);
end if;
end;

/*
系统事件触发器
*/

conn sys/sys as sysdba;
create table event_table(event varchar2(30),time date);
/

create or replace trigger tr_startup
after startup on database
begin
insert into event_table values(ora_sysevent,sysdate);
end;
/
/*
登录退出触发器
*/
create table log_table(
name varchar(20),
logon_time date,
logoff_time date,
address varchar2(100)
);
create or replace trigger tr_logon
after logon on database
begin

insert into log_table(name,logon_time,address)
values(ora_login_user,sysdate,ora_client_ip_address);
end;
/

create or replace trigger tr_logon
before logoff on database
begin

insert into log_table(name,logoff_time,address)
values(ora_login_user,sysdate,ora_client_ip_address);
end;

/*
DDL触发器
*/
conn sys/sys as sysdba;

create table event_ddl(
event varchar2(20),
username varchar2(10),
owner varchar2(20),
objname varchar2(20),
objtype varchar2(10),
time date
);

create or replace trigger tr_ddl
after ddl on scott.schema
begin
insert into event_ddl values(ora_sysevent,ora_login_user,ora_dict_obj_owner,ora_dict_obj_name,ora_dict_obj_type,sysdate);
end;

/*
管理触发器
*/
--1显示触发器信息
select trigger_name ,status from user_triggers
where table_name='EMP';
--2禁止触发器
alter trigger tr_sec_emp disable;
--3激活触发器
alter trigger tr_sec_emp enable;
--4禁止或激活所有触发器
alter table emp disable all triggers;
alter table emp enable all triggers;
--5重新编译触发器
--当修改表结构时,触发器状态变为invalid,重新编译可使触发器生效
alter trigger tr_sec_emp compile;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值