(23)触发器

单sql语句触发器
当员工表进行增删改时,使得t2员工数目变化和总额发生改变

 create table t1(
 id int,
 name varchar(10),
 salary int);

 create table t2(
  user_total int ,
  salary_total int);

//创建触发器,当在t1表添加t1记录时,在t2表用户总数+1,总额增加

create trigger t1_ad
after delete on t1
for each row
update t2 set
user_total=user_total-1,salary_total=salary_total-old.salary;

//创建触发器,当在t1表删除t1记录时,在t2表用户总数-1,总额减少

create trigger t1_ad
after delete on t1
for each row
update t2 set
user_total=user_total-1,salary_total=salary_total-old.salary;

//创建触发器,当在t1表更新(更新销售额)t1记录时,t2总额改变

create trigger t1_au
after update on t1
for each row
update t2 set
salary_total=salary_total-old.salary+new.salary;

update t1 set salary=6000 where id=5;

//触发器操作是个事务操作,要么不做,要么做完。测试
在下面的事务中,在事务没有提交时,即使在这个客户端查询已经修改了数据,但是另外开启一个客户端,数据仍然是不变的。
begin;
update t1 set salary=5000 where id=5;
commit;
所以,不会发生当一个操作执行后,正好电脑宕机,另一个操作不执行的情况。

创建多执行的触发器

create table t3 (
 id int,
 name varchar(20),
 gid int//用户的等级,0代表普通用户 1代表VIP用户
);

insert into t3 values(1,'aa',0),(2,'bb',1),(3,'cc',0),(4,'dd',1),(5,'ee',0),(6,'ff',0),(7,'gg',1),(8,'hh',0),(9,'ii',1),(10,'gg',0)//
create table t4(
  user_total int,//普通用户总数
  vip_total int);//VIP用户总数
insert into t4 values(5,5); 

因为在条件判断时,会有;而mysql默认将分号作为执行语句的结束,导致else不会执行,所有要将语句结束条件改变
//插入
delimiter //
create trigger t3_ai
after insert on t3
for each row 
if new.gid=0 then update t4 set user_total=user_total+1;
else update t4 set vip_total=vip_total+1;
end if;
//

insert into t3 values(11,'hh',0)//

//删除
delimiter //
create trigger t3_ad
after delete on t3
for each row 
if old.gid=0 then update t4 set user_total=user_total-1;
else update t4 set vip_total=vip_total-1;
end if;
//

delete from t3 where id=11//

if语句触发器
//修改[这个可以修改name和gid]
if:当新值和旧值不同时,新值为0,则说明旧值为1,则对t4的操作普通用户+1,VIP用户-1
elseif :当新值和旧值不同时,新值为1,则说明旧值是0,则对t4的操作普通用户-1,VIP用户+1
对于条件判断的其他情况,即新值和旧值相同,则不同修改t4表

delimiter //
create trigger t3_au
after update on t3
for each row 
if old.gid!=new.gid and new.gid=0 then update t4 set user_total=user_total+1,vip_total=vip_total-1;
elseif old.gid!=new.gid and new.gid=1 then update t4 set user_total=user_total-1,vip_total=vip_total+1;
end if;
//

case语句触发器:

delimiter //
create trigger t3_acu
after update on t3
for each row 
case 
when old.gid!=new.gid and new.gid=0 then update t4 set user_total=user_total+1,vip_total=vip_total-1;
when old.gid!=new.gid and new.gid=1 then update t4 set user_total=user_total-1,vip_total=vip_total+1;
end case;
//

【注意:对一个表t3 创建触发器 after update on t3 只能创建一个触发器,而不能对更新这个表创建多个触发器,否则会报错】

loop语句触发器
功能:活动表每增加一行则:1 随机挑选一名用户信息 2 将用户信息插入到获奖者表 3 循环指定次数
用户信息表已有t3

//活动日期和总获奖人数

create table t5 (
event_date date,
winnum int)//

//获奖的用户表
create table t6(
 id int,
 name varchar(20),
 gid int,
event_date date)//

create trigger t5_ai
 after insert on t5
 for each row
 begin
 declare mnum int default 0;//循环变量
 declare wnum int;//获奖者数量 循环变量和获奖者数量不能用同一个表示
 declare tnum int;//总的用户人数
 declare rnum int;//随机数
 declare tdate date;//活动日期
 select count(*) into tnum from t3;
 set tdate=new.event_date;
 set wnum=new.winnum;
 t5_loop:loop
 set mnum=mnum+1;
 set rnum=floor(1+rand()*tnum);//生成总用户的随机数,即任意编号
 insert into t6 select id,name,gid,tdate from t3 where id=rnum;
 if mnum >=wnum
 then leave t5_loop;
 end if;
 end loop t5_loop;
 end;//

insert into t5 values('2017-10-26',3)//

repeat语句的触发器[执行循环,直到条件退出循环]

 repeat 
 set mnum=mnum+1;
 set rnum=floor(1+rand()*tnum);
 insert into t6 select id,name,tdate from t3 where id=rnum;
 until mnnum>=winnum;//这里对结束进行了精简
 end repeat;
 end;

while 语句的触发器[当..执行]

  while munm<winnum
  set mnum=mnum+1;
  set rnum=floor(1+rand()*tnum);
  insert into t6 select id,name,tdate from t3 where id=rnum;
  end while;
  end;
  //

相同的表,相同的事件(before、after)只能创建一个触发器
当触发器使用到流程控制语句时,特别是循环时要注意性能问题
及时删除不需要的触发器【因为可能会在不知道的情况下多些操作】

表的拥有者即创建表的用户可以在表上创建触发器,而且一张表上可以创建多个触发程序。
触发执行sql语句:触发执行的sql语句,若该触发程序要执行多条sql语句,要将多条语句放在begin、end块中。

posted @ 2017-11-04 15:46  测试开发分享站  阅读(116)  评论(0编辑  收藏  举报