05 Oracle触发器

触发器: 当满足触发器条件,则系统自动执行触发器的触发体。 触发时间:有 before,after.触发事件:有 insert,update,delete 三种。触发类型:有行触发、语句触发。

before:先执行,再操作
after: 先操作,再执行。

当执行insert的时候, :new存在 ,:old没有
当执行delete的时候, :new不存在,:old存在
当执行update的时候, :new存在,:old存在 

1.创建触发器

--创建插入或者是修改触发器trig1
create or replace trigger tirg1
before insert or update on 成绩表 for each row
--加上了for each row 就是行级别,没有就是表级别
begin
    dbms_output.put_line('触发器trig1响应了')
end;
set serverout on --打开触发器响应
insert into 成绩表 values(5,'A',50); --数据插入之后,显示触发器trig1响应了

 2.触发器的应用一:当用户插入记录到student表时,不能插入sno是负值的记录

create or replace trigger trig2
before insert on student for each row
begin
    if :new.sno < 0 then
        --rollback;--回滚不能出现在触发器中
        raise_application_error(-20000,'学号错误,不能是负值!');
    end if;
end;

总结:触发器中不能使用rollback,commit,create,drop,alter,saveopint等。
如果触发器的plSQL内使用:new :old,就必须是行级触发器,for each row 必须存在。

update student set  sage = 41 where sno = 1;
    sno        sname        sage
    1        tom            21
先把1 tom 21记录删除,然后再把1 tom 41记录加到表里面去。

3.触发器的应用二:当用户插入记录到student表时,如果插入sno是负值,那么把sno改为相反数,再插入

create or replace trigger trig3
before insert on student for each row
begin
    if :new.sno < 0 then --如果学号为负
        :new.sno :=- :new.sno
    end if;
end;

4.触发器修改视图

--把姓名为Kite的人住址改为安阳
update view_stu_add set zz='安阳' where sname='Kite';--更新不了

create or replace trigger tri_view
instead of update on view_stu_add for each row
declare
    s_no number :=0;
begin
    --从student表取得姓名,得到sno(学号)赋值给s_no
    select sno into s_no from student where sname =:old.sname;
    delete address where sno = s_no;--删除address表中sno为s_no的记录
    insert into address values(s_no,:new.zz);--然后再插入记录 (学号,地址)
end;
update view_stu_add set zz='安阳' where sname = 'Kite'; --更新成功
--这个触发器其实就是更新address表。

5.触发器记录表操作(增删改),当用户对成绩表进行操作时,把情况记录下来。

create or replace trigger trig5 
before insert or update or delete on 成绩表 for each row
begin
	if inserting then --inserting 表示插入
		dbms_output.put_line('插入的学生学号是:'||:new.code||',名称是:'
		||:new.name||',成绩是:'||:new.score);
	end if;
	
	if updating then
		dbms_output.put_line('原始记录的学生的学号是:'||:old.code||',名称是:'
		||:old.name||',成绩是:'||:old.score||'。新的学生学号是:'||:new.code||'名称是:'
		||:new.name||',成绩是:'||:new.score);
	end if;
	
	if deleting then 
		dbms_output.put_line('删除的学生学号是:'||:old.code||',名称是:'
		||:old.name||',成绩是:'||:old.score);
	end if;
end;
update 成绩表 set score =100 where code = 1;
--其实可以把记录保持到表里面,而且还能够显示时间,这样就可以随时掌握用户对表的操作情况。

6.数据库启动关闭时,利用触发器把记录保持到表里

create table event_table(
    event varchar2(30),
    time date
)
create or replace trigger tr_startup
after startup on database --数据库启动,是启动之后才能记录,所以用after
begin
	insert into event_table values(ora_sysevent,sysdate);
end;

--数据库关闭
create or replace trigger tr_shutdown
before shutdown on database --关闭之前记录的,所以用before
begin
	insert into event_table(ora_sysevent,sysdate);
end;

shutdown immediate  --关闭数据库

startup --启动数据库

select event,to_char(time,'yyyymmdd hh2:mi:ss') from event_table;

7. 用户登录退出触发器

--用户登录触发器
create or replace trigger tr_logon
after logon on database --用户登录是登录之后才能记录
before
	insert into log_table(username,logon_time,address)
				values(ora_login_user,sysdate,ora_client_ip_address);
end;

--用户退出触发器
create or replace trigger tr_logoff
before logon on database --用户退出是退出之前才能记录
before
	insert into log_table(username,logoff_time,address)
				values(ora_login_user,sysdate,ora_client_ip_address);
end;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值