Msql触发器,trigger


场景:

日志系统,记录对学生表有哪些操作!


解决的问题:

    1:得到每条学生记录被修改的时机,才能发出记录日志动作

    2:执行某段操作,需要得到 当前处理的记录的信息


触发器:一种编程设计!类似JS的基于事件编程的程序设计的理念!可以在某个表的每条记录上设置一个事件,从而对该表上的某些操作加以监听!一旦所监听的行为出现,则会执行相应的代码。


JS事件:

<button οnclick="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')
;

wKioL1ZsEkzgaxaiAAA2QS9qzhs163.jpg


建立日志表:


create table student_log(
id int primary key auto_increment,
op varchar(10),
op_time datetime,
ps varchar(255)
);


wKiom1ZsEwHCuDLLAAAmm4oUAF8572.jpg


插入一条数据:

insert into select_student values (null,'欧阳锋','male',22,2345.36,178.00);



wKiom1ZsFAWgBlyWAAB0qKFVuCc601.jpg


日志表内的记录自动增加:


wKioL1ZsFFPhio7MAAAyZ1iy7YE619.jpg


可见 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;

    wKioL1ZsGHmQpbHUAACMDXTWaI8399.jpg


    查看日志文件:

        wKiom1ZsGPDQHL1AAAA5YyDc5c8917.jpg


此时,留意一下触发器与具体的语法的执行时机:

如: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 ;


测试:

wKioL1ZsIlajXS0cAACj81RikSs336.jpg


注意:关于触发器

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