mysql学习-001触发器知识总结

学习mysql中触发器的使用

触发器非常消耗资源。如非必要,尽量少使用触发器。
如果一定要使用的话,一定要谨慎的使用,确保它是高效的。
触发器是针对每一行的;对增删改查非常频繁的表,切记不要使用触发器,因为这样会非常的消耗资源。

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_event详解:
  1. insert 型触发器:插入某一行时集合触发器。可能通过insert,load data ,replace 语句触发。其中load data语句用于将一个文件装入到一个数据表中,相当于一系列的insert操作。
  2. update 型触发器:更改某一行时激活触发器。可能通过update语句触发。
  3. delete 型触发器:删除某一行时激活触发器,可能通过delete ,replace语句触发。

trigger_order是mysql5.7之后的一个功能,用于定义多个触发器,使用follows(尾随)或precedes(在…之前)来选择触发器执行的先后顺序。

关于mysql存储过程的definer的问题

   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’用户的权限,即最高管理员权限。

案例:

案例1.创建只有一个执行语句的触发器

触发结构:

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());
案例2.创建有多个执行语句的触发器
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;

new 和old 详解

对于INSERT语句,只有NEW是合法的;对于DELETE语句,只有OLD才合法;而UPDATE语句可以在和NEW以及OLD同时使用。

案例3 真对用户信息表来写触发器,往日志表中添加日志
--触发器案例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来实现触发器

创建相应的表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);

尚未完成
链接: 学习网页.

你可能感兴趣的:(mysql)