Msql触发器,trigger
场景:
日志系统,记录对学生表有哪些操作!
解决的问题:
1:得到每条学生记录被修改的时机,才能发出记录日志动作
2:执行某段操作,需要得到 当前处理的记录的信息
触发器:一种编程设计!类似JS的基于事件编程的程序设计的理念!可以在某个表的每条记录上设置一个事件,从而对该表上的某些操作加以监听!一旦所监听的行为出现,则会执行相应的代码。
JS事件:
<button onclick="alert('Hello');" /> click me </br >
记录 = button
(修改,删除,增加) = click
执行操作 =alert('Hello');
以上的所有行为,都是采用 sql 完成的
语法:
create trigger 触发器名字 触发条件,监听的内容,触发后执行的操作;
create trigger trigger_name trigger_time trigger_event on tbl_name for each row trigger_stmt;
其中,触发条件,事件。是由事件的时机,与事件的内容组成
时机:之前 before 和之后 after
内容:增加 insert,删除 delete,修改 update
因此,一共只有六种事件:
before insert , before delete , before update
after insert , after delete , after update
监听的主体是由表中的记录发出的
on table_name for each row
执行的操作,就是一段 sql 的集合!
create trigger test_trigger after insert on select_student for each row insert into student_log values (null,'insert',now(),'new ID') ;
建立日志表:
create table student_log( id int primary key auto_increment, op varchar(10), op_time datetime, ps varchar(255) );
插入一条数据:
insert into select_student values (null,'欧阳锋','male',22,2345.36,178.00);
日志表内的记录自动增加:
可见 insert into student_log触发程序,执行成功!
如何在触发程序中得到当前触发的记录信息:
有两个:new , old
new and old , 表示触发程序的记录!
new : 新的记录
old : 旧的记录
取决于当前操作(insert , update , delete)去使用其中某个:
insert , 增加记录,没有旧记录,只有new关键字可以使用
delete , 删除记录,没有新记录,只有old关键字可以使用
update , 更新,既有新纪录,也有旧记录,更新前是旧记录,而更新后是新记录
记录:当学生被删除之后,记录日志,要求记录学生的ID
创建删除日志表:
create trigger log_del_stu after delete on select_student for each row insert into student_log values (null,'delete',now(),old.id) ;
测试:删除记录:
delete from select_student where id=46;
查看日志文件:
此时,留意一下触发器与具体的语法的执行时机:
如:insert into table操作
判断,是否有 before insert 触发器,有则执行触发程序
真正执行 insert into
判断,是否有 after insert 触发器!有则执行触发程序
更新日志:
记录更新日志,要求是:只对某部分同学完成更新日志
只记录身高超过175学生的更新记录!需要记录修改前后的身高信息
需要额外的增加条件判断
create trigger log_upd_stu after update on select_student for each row if old.height > 175 then insert into student_log values (null,'update',now(),concat(old.id,':',old.height,'--',new.height)); end if; ;
逻辑分支语句:
if 条件 then
语句体
else if 条件 then
语句体
......
else
语句体
end if;
sql语句结束符问题:
可以修改最外层的语句结束符来达到目的!
delimiter $$
将语句结束符修改成:$$
记住用完之后要修改成分号为结束符
因此,上面的语句需要修改成为:
delimiter $$ create trigger log_upd_stu after update on select_student for each row if old.height > 175 then insert into student_log values (null,'update',now(),concat(old.id,':',old.height,'--',new.height)); end if; $$ delimiter ;
如果触发程序由多条语句组成块。此时就需要使用 begin end 将语句块包裹
因此,上面的创建触发器语句的完整写法为:
delimiter $$ create trigger log_upd_stu after update on select_student for each row begin if old.height > 175 then insert into student_log values (null,'update',now(),concat(old.id,':',old.height,'--',new.height)); end if; end $$ delimiter ;
测试:
注意:关于触发器
1:一个表上的一个事件只能有一个触发器,如果需要,只能将原始的去掉,再新增
删除触发器:drop trigger 触发器名称;
2:只要事件发生,触发程序就可能执行!一条语句可能触发多个触发程序!
例如:
insert into on duplicate key update;
before insert trigger , insert 操作失败 before update trigger , update 操作 , after update
before insert trigger , insert 操作成功 after insert trigger