mysql触发器

第七章 触发器

7.1、触发器的含义与作用

 (1)触发器(trigger)是由事件来触发某个操作,主要是由insert update delete等事件来触发某种特定的条件,满足触发器的触发条件时,数据库就会执行触发器定义的程序语句,

     比如:当学生表当中增加了一个学生记录,学生的总数就必须同时改变。可以在这里创建一个触发器,每次增加一个学生的记录。就执行一次计算学生的总数量的操作。

    这一可以保证每次增加学生后的记录统计一直保持最新。。

  触发器触发的执行语句可以只有一个。也可能有多个。 


 (2)在进行dml操作的时候(insert,update,delete),可以对事件进行监听和响应,这种机制在数据库中
叫做触发器。 触发器与永久性表关联,只能建在永久性表上面,不能是temporary表或view,且只有insert,update
,delete  三种事件。
  
 (3)自动在内存中生成临时的new表和old表,触发器执行完成后自动销毁
  insert操作进来的数据放在new表中
  delete操作删除的数据放在old表中
  update操作更新前的数据放在old表中,更新后的数据放在new表中
  old表是只读的,而new表在触发器程序中可以重新赋值

 

 

触发器的触发时机有2种:

before、after 

 

 before:在执行操作之前要运行的语句
 after:在执行操作之后要运行的语句

 

语法:( mysql> help create trigger )

   create trigger 触发器名称  before|after 触发事件 on 表名 for each row 执行语句

 

     before指触发事件之前执行的触发语句。

     After   表示在触发事件之后执行语句

     触发事件包括(insert update delete)等

     on 表名  在XXX表之上

     执行语句 指的是XXSQL语句和触发事件类型要对应

 

  例1:创建一个触发器,当输入的学生成绩小于0时设置为0,当大于100时设置为100

       mysql> delimiter //

        mysql> create trigger tr_stu_bf
    -> before insert on stu
    -> for each row
    -> begin
    -> if new.score < 0 then
    -> set new.score=0;
    -> elseif new.score > 100 then
    -> set new.score=100;
    -> end if;
    -> end
    -> //

       mysql> delimiter ;

 

 例2:当学生的score大于等于90时,将学生的id和名字写入yxstu表中;

    注意:score是stu_info表中的字段。yxstu是创建的新表
  mysql> create trigger tr_ins_af
    -> after insert on stu
    -> for each row
    -> begin
    -> if new.score >= 90 then
    -> insert into yxstu values(new.id,new.name);
    -> end if;
    -> end
    -> //

 

 

例3:新建销售表sales,包含商品id,商品名,商品类型(代号),销售数量四个字段;新建库存表stor
e,包含商品id, 商品名,商品类型,库存数量四个字段,要求在库存表中加入4条数据,库存量都为100;然后每销
售一件商品则相应商品的库存量就减少商品的销售量;当删除销售表里的记录时则将库存表相应的记录也删
除库存表      

      1  华为手机  p001  100
      2  小米手机  p002  100
      3  中兴手机  p003  100
      4  vivi手机  p004  100

 

mysql> create table sales(id int , name varchar(20),scode varchar(10) primary key, num varchar(20));
 

 

mysql> delimiter &&

mysql> create trigger s_s after insert on sales for each row

     > update store set Knum=Knum - new.num where Dh=new.Dh;&&

mysql> delimiter ;

mysql> insert into sales(1,'华为手机','p001','3')
 

 

mysql>select * from store;

 

例4: 创建学生成绩表score,包括记录ID,学生编号(s001),学生姓名,数学、语文、英语三门课程
的成绩;新建学生情况表scond,包含包括记录ID,学生编号(s001),学生姓名,学生表现四个字段,每插入一条成
绩表记录时, 则在学生情况表里插入相应的信息,如果学生三门课的平均成绩大于等于90分,则学生表现字段为"优秀",如 果三门课的平均成绩为>=70并<90则为良好,大于等于60小于70为及格,小于60为不及格。
  mysql> create table score(id int primary key,sno varchar(6),sname varchar(20),ma
th float(4,1),chinese float(4,1),english float(4,1));    

   
mysql> create table scond(id int primary key,sno varchar(6),sname varchar(20),pe
rform varchar(10));


mysql> create trigger tr_scond_in_af after insert on score for each row

    -> begin 

    ->if new.math+new.chinese+new.english>270 then 

    -> insert into scond values(new.ID,new.scode,new.sname,'优秀');

    -> elseif new.math+new.chinese+new.english<=270 &&  new.math+new.chinese+new.english>=210 then      ->insert into scond values(new.ID,new.scode,new.sname,'良好'); 

    ->elseif new.math+new.chinese+new.english>=180 &&  new.math+new.chinese+new.english<210 then

    ->insert into scond values(new.ID,new.scode,new.sname,'合格'); 

    ->elseif new.math+new.chinese+new.english<180  then 

    ->insert into scond values(new.ID,new.scode,new.sname,'不合格');  

    ->end if;

    ->end

    ->//

 

例5:如果在score表中删除学生记录,则将scond表中相应的学生记录也一起删除。

            mysql> create trigger tg_sc_del_af
    -> after delete on score
    -> for each row
    -> begin
    -> delete from scond where sno=old.sno;
    -> end
    -> //
       
  例6:当更新score表中数学、语文和英语成绩时,检查是否合理,如果低于0分则为0,高于100分则
为100。       

mysql> create trigger tg_sc_up_bf
    -> befor update on score
    -> for each row
    -> begin
    -> if new.math < 0 then
    -> set new.math=0;
    -> elseif new.math >100 then
    -> set new.math=100;
    -> elseif new.chinese < 0 then
    -> set new.chinese=0;
    -> elseif new.chinese >100 then
    -> set new.chinese=100;
    -> elseif new.english < 0 then
    -> set new.english=0;
    -> elseif new.english >100 then
    -> set new.english=100;
    -> end if;
    -> end
    -> //
    
  查看触发器信息

   查看所有触发器,提前要进入某数据库
  mysql> show triggers\G
  mysql> select * from information_schema.triggers\G
  
  删除触发器
  mysql> drop trigger tg_sc_up_bf;

 

==================================

 

 

 

7.2、创建触发器

(1) 创建一个表alvin

create table alvin(

     userid int(10),

    username varchar(20),

    old int(4),

address varchar(30));

 

(2) 创建一个表为trigger_time 用来存放触发后条件的结果

create table trigger_time(

zhixing_time time);

 

(3)、创建只有单个执行语句的触发器

create trigger alvin1 before insert  on alvin for each row                          

>insert into trigger_time values(now());

 

 

(4)、创建有多个执行语句的触发器

444444444444.png

 

举例一、

mysql> delimiter &&   

#告诉MYSQL该命令段下面的内容在提示结束后再执行分析。默认是以分号(;)执行  # delimiter 定界符

mysql> create trigger alvin3 after delete on alvin for each row

    -> begin

    -> insert into trigger_time(zhixing_time) values('21:01:01');

    -> insert into trigger_time(zhixing_time) values('22:01:01');

    -> end

    -> &&

 

mysql> delimiter    ;   #结束退出,注意分号要有空格

 

mysql> select * from alvin;  

+--------+-------------+------+----------+

| userid | username    | old  | address  |

+--------+-------------+------+----------+

|    110 | zengxiaohua |   28 | tianxing |

+--------+-------------+------+----------+

 

mysql> delete from alvin where userid='110';  #执行删除动作看看触发器是否成功

 

mysql> select * from trigger_time;    #:查看触发器的执行结果

+--------------+

| zhixing_time |

+--------------+

| 19:09:41     |

| 21:01:01     |

22:01:01     |

+--------------+

3 rows in set (0.00 sec)

 

举例二、

 alvin1表存放了学生的信息。每次增加(insert)一个学生的信息。就触发一次统计。统计结果存入aac表里面;

 首先创建一个alvin1表结构

mysql> create table alvin1(

user_id int(10),

username varchar(20),

old tinyint(4),

address varchar(30));

 

mysql> create table aac(

my_count int);

 然后开始创建一个触发器

mysql> delimiter &&

 

mysql> create trigger alvin123 before insert on alvin1 for each row 

begin

declare ycount int(10);               #:申明变量类型

set ycount=(select count(*) from alvin1);  #:给变量赋值

insert into aac(my_count) values(ycount)#:调用变量

end &&

 

mysql> delimiter ;

mysql> insert into alvin1 values('1001','zhangsan','18','China'); 开始测试

mysql> select * from aac;                  查看触发器统计的结果。

 

 

 

小技巧:

所有触发器的信息都存在information_schema库中的triggers表里面,

在使用select 查询单个触发器的时候。可以根据triggers表里面的字段名称

Trigger_name字段进行查询。

 

mysql> select * from triggers where trigger_name='alvin1'\G;

 

7.4、删除触发器

语法:555555555555555.png

 

 

(1)、删除alvin1触发器

mysql> use zytest;

mysql> drop trigger alvin1;

 

 

练习题目
需求:创建个两个表product和operate表,

6666666666666.png

 

 777777777777777.png

 

 

  操作要求:

(1)、在product表上分别创建

before insert   把结果写入operate表(内容为:op_id(统计product总数量),操作方式为insert,操作时间now() )

after update   把结果写入operate表(内容为:op_id(统计product总数量),操作方式为update,操作时间now() )

after delete   把结果写入operate表(内容为:op_id(统计product总数量),操作方式为delete,操作时间now() )

 

3个触发器。触发器名称分别为product_bf_insert 和product_af_update 和

product_af_delete

(2)、对product表分别执行insert、update和delete操作

(3)、删除product_bf_insert 和product_af_update这两个触发器

(4)、最后再查看剩余的触发器的详细信息,以及在operate表里面的内容,是否有触发成功的结果。

 =============  答案分析  ==============

create table product(
id int(10) primary key not null,
name varchar(20) not null,
function varchar(50),
company varchar(20) not null,
address varchar(50));

create table operate(
op_id int(10) not null,
op_type varchar(20) not null,
op_time  time not null);

(1)
触发器1
delimiter &&
create trigger product_bf_insert before insert
on product for each row
begin
declare num1 int(20);
set num1=(select count(*) from product);
insert into operate(op_id) values(num1,'insert',now());

end

&&
delimiter  ;


触发器2
delimiter &&
create trigger product_af_update after update
on product for each row
begin
declare num2 int(20);
set num2=(select count(*) from product);
insert into operate(op_id)  values(num2,'update',now());
end
&&
delimiter ;


触发器3
delimiter &&
create trigger product_af_delete after delete
on product for each row
begin
declare num3 int(20);
set num3=(select count(*) from product);
insert into operate(op_id) values(num3,'delete',now());
end
&&
delimiter ;

(2)
 插入
desc product;
insert into product values('110','zhangsan','jisuan','hunan','hunan');
select * from product;
select * from product_bf_insert;
更新
update product set name='xjm' where id='110';

删除
delete from product where function='计算';

(3)
select * from information_schema.triggers\G;
drop trigger product_bf_insert;
drop trigger product_af_update;
select * from information_schema.triggers\G;

posted @ 2018-03-05 11:27  你的快递到了吗  阅读(262)  评论(0编辑  收藏  举报