触发器非常消耗资源。如非必要,尽量少使用触发器。
如果一定要使用的话,一定要谨慎的使用,确保它是高效的。
触发器是针对每一行的;对增删改查非常频繁的表,切记不要使用触发器,因为这样会非常的消耗资源。
create [definer = {
user | current_user}]
trigger trigger_name
trigger_time trigger_event
on table_name for each row
[trigger_order]
trigger_body
trigger_time:{before|after}
trigger_event:{
insert|update|delete}
trigger_order:{follows|precedes} other_trigger_name
before 和after参数指定了触发执行的时间,在时间之前或是在之后。
for each row 表示任何一条记录上的操作满足触发事件都会触发该触发器,也就是说触发器的触发频率是针对每一行数据触发一次。
trigger_order是mysql5.7之后的一个功能,用于定义多个触发器,使用follows(尾随)或precedes(在…之前)来选择触发器执行的先后顺序。
update mysql.proc set definer='root@localhost' where db='db_name';
方法二:修改sql security
sql secuirty的值决定了调用存储过程的方式,取值 :definer或者invoker
definer:在执行存储过程前验证definer对应的用户如:[email protected].%是否存在,以及是否具有执行存储过程的权限,若没有则报错
invoker:在执行存储过程时判断inovker即调用该存储过程的用户是否有相应权限,若没有则报错。
修改语法:
alter procedure pro_name sql security invoker;
关于这个’root’@’%’ ,这个形式就是’A’@‘B’的形式,它的意思是,密码正确的前提下,IP或域名为B才可以使用MYSQL服务器上的用户名为A的权限。而’root’@’%'的意思是,密码正确的前提下任何人都可以使用MYSQL名为’root’用户的权限,即最高管理员权限。
触发结构:
create trigger 触发器名
before|after
触发事件
on 表名
for each row
执行语句;
具体实现:
创建一个名为triga的触发器,一旦在work表中有插入动作,就会自动往time表里面插入当前时间。
create trigger triga after insert
on work for each row
insert into time values(now());
create trigger 触发器名 before | after 触发事件
on 表名 for each row
begin
执行语句
end;
具体案例:定义一个触发器,一旦有满足条件的删除操作,就会执行begin 和end中的语句。
create trigger trig2 before delete
on work for each row
begin
insert into time values(now());
insert into tab2 values(now());
end;
对于INSERT语句,只有NEW是合法的;对于DELETE语句,只有OLD才合法;而UPDATE语句可以在和NEW以及OLD同时使用。
--触发器案例1
create table test.users(
id int(11) unsigned not null auto_increment,
name varchar(255) character set utf8mb4 default null,
add_time int(11) default null,
primary key (id),
key name (name (250)) using btree
) engine=myisam auto_increment=1000001 default charset=latin1;
drop table test.users_logs;
create table test.users_logs(
id int(11) not null auto_increment,
log varchar(255) default null comment '日志说明',
primary key (id)
) engine=InnoDB default CHARSET=utf8mb4 comment='日志表';
## 需求:挡在users中插入一条数据,就在logs中生成一条信息。
-- 创建触发器
delimiter $
create trigger trigger_users_logs after insert on test.users for each row
begin
declare s1 varchar(40) character set utf8;
declare s2 varchar(20) character set utf8;
set s2="is created";
set s1 = concat(new.name,s2);
insert into test.users_logs(log) values(s1);
end $
delimiter;
insert into test.users (name) values('aaa');
创建相应的表goods 和 ord表
drop table goods;
create table test.goods(
gid int default null comment '商品id',
name varchar(20) default null comment '商品名称',
num smallint default null comment '商品库存数量'
);
drop table test.ord;
create table test.ord(
oid int default null comment '订单编号',
gid int default null comment '商品编号',
much smallint default null comment '订购数量'
);
insert into test.goods values(1,'cat',30);
insert into test.goods values(2,'dog',40);
insert into test.goods values(3,'pig',50);
1)触发器1:实现一个简单地触发器,
每当向ord表中插入数据都会自动的将goods中gid=1的商品的数量减去2
触发器逻辑存在问题;
drop trigger if exists kc_a;
create trigger after insert on ord
for each row
begin
update goods set num=num-2 where gid=1;
end;
insert into ord values(1,1,2);
select * from goods;
2)触发器2:实现需求:当下订单时,减少相应的货品的库存量;
create trigger kc_b
after insert on ord
for each row
begin
update goods set num=num-new.much where gid =new.gid;
end;
insert into ord values (1,2,5);
修改ord 表结构
drop table test.ord;
CREATE TABLE `ord` (
`oid` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单编号',
`gid` int(11) DEFAULT NULL COMMENT '商品编号',
`much` smallint(6) DEFAULT NULL COMMENT '订购数量',
PRIMARY KEY (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3)触发器3:实现需求:当删除订单时,增加相应的修改货品的库存量
create trigger kc_c
after delete on ord
for each row
begin
update goods set num=num+old.much where gid=old.gid;
end;
select * from goods;
select * from ord;
delete from old where much =5;
select * from ord;
select * from goods;
insert into ord(gid,much) values(3,3);
delete from ord where oid=2;
4)触发器: 当更新订单的购买数,修改相应的修改商品的库存量;
-- 当更新订单的购买数,修改相应的修改商品的库存量;
-- 假设现在还有2号商品30个,下订单购买5个后,goods中2号商品只剩25个
-- 后面感觉买多了,就退掉两个商品,修改订单中购买的2好商品订单,
-- 将5个商品更改成3个,这样就
drop trigger if exists kc_d;
create trigger kc_d
before update on ord
for each row
begin
update goods set num=num+old.much-new.much where gid = new.gid;
end;
select * from ord;
select * from goods;
insert into ord(gid,much) values(2,8);
update ord set much =5 where much=8;
5)触发器需求:在用户订购了超过库存的订单后,会修改订单的订购数量,使订购数量的最大值和库存值相同,判断:如果订购量>库存量,然后做将订购量改为库存量。
-- 在用户订购了超过库存的订单后,会修改订单的订购数量,
-- 使订购数量的最大值和库存值相同,
-- 判断 ,订购量>库存量,然后做将订购量改为库存量。
create trigger kucunf
before insert on orda
for each row
begin
declare restNum int;
select num into restNum from goodsa where gid=new.gid;
if new.much > restNum then
set new.much = restNum;
end if;
update goodsa set num=num-new.much where gid=new.gid;
end;
insert into goodsa values(1,'aaa',100);
select * from goodsa;
insert into orda(gid,much) values(1,20);
select * from orda;
insert into orda(gid,much) values(1,88);
尚未完成
链接: 学习网页.