(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;
==================================
(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)、创建有多个执行语句的触发器
举例一、
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;
语法:
(1)、删除alvin1触发器
mysql> use zytest;
mysql> drop trigger alvin1;
操作要求:
(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;