时间:2021-07-01 10:21:17 帮助过:3人阅读
以eschop的商品表,跟订单表为例: 新建商品表 create table goods( id int auto_increment primary key, #商品id name varchar(30) not null default '',#商品名 num tinyint not null default 0 #商品数量 )engine myisam default charset utf8; 新建订单变 create table indent( oid int auto_increment primary key, #订单id gid int not null default 0, #商品id much tinyint not null default 0 #购买数量 )engine myisam default charset utf8; mysql> desc goods; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(30) | NO | | | | | num | tinyint(4) | NO | | 0 | | +-------+-------------+------+-----+---------+----------------+ 3 rows in set mysql> desc indent; +-------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+----------------+ | oid | int(11) | NO | PRI | NULL | auto_increment | | gid | int(11) | NO | | 0 | | | much | tinyint(4) | NO | | 0 | | +-------+------------+------+-----+---------+----------------+ 插入演示数据: insert into goods values(1,'三星手机',12),(2,'ipad电脑',19),(3,'摩托罗拉mp3',38); mysql> select * from goods; +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 38 | +----+-------------+-----+ 手工给订单表添加购买记录: insert into indent(gid,much)values(3,2); mysql> select * from indent; +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 1 | 3 | 2 | +-----+-----+------+ 1 row in set 手工给商品表减少商品信息: update goods set num=num-2 where id=3; mysql> select * from goods; +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 36 | +----+-------------+-----+ 3 rows in set 修改mysql的结束符: mysql> delimiter $ ------------------------------------------- 创建触发器 create trigger tg1 after insert #在插入之后触发 on indent for each row #固定写法 begin update goods set num=num-1 where id=3; end $ ------------------------------------------ 模拟用户下订单流程 商品表: +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 36 | +----+-------------+-----+ 订单表: +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 1 | 3 | 2 | +-----+-----+------+ ①下订单 insert into indent(gid,much)values(2,4)$ ②查看订单表 +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 1 | 3 | 2 | | 2 | 2 | 4 | +-----+-----+------+ ③商品表应该减少 +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 结论:显然用户下了2号订单,下了4件商品,订单生成了!商品却没减少,还出现了错误! ----------------------------------------- 正确的创建触发器: create trigger tg2 after insert on indent for each row begin update goods set num=num-new.much where id=new.gid; end $ -----------------------------------下订单insert触发器----------------------------------------- 出现错误:因为一张表不能同时被2个触发器监视,所以要删除开始创建的触发器 mysql> drop tg1$ Query OK, 0 rows affected mysql> show triggers$ Empty set 开始购买商品(清空订单表): mysql> select * from goods; -> $ +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 3 rows in set mysql> insert into indent(gid,much)values(2,4)$ Query OK, 1 row affected mysql> select * from indent$ #下订单成功 +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 1 | 2 | 4 | +-----+-----+------+ 1 row in set mysql> select * from goods$ #对应商品自动减少OK +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 15 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 3 rows in set ------------------------------------------取消订单delete触发器------------------------------------ create trigger tg3 after delete on indent for each row begin update goods set num=num+old.much where id=old.gid; end $ 注:真项目中,永远不会物理删除订单 ---------------------------------- 模拟取消订单: mysql> select * from goods$ +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 15 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 3 rows in set mysql> select * from indent$ +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 1 | 2 | 4 | +-----+-----+------+ 1 row in set mysql> delete from indent where oid=1$ Query OK, 1 row affected mysql> select * from indent$ Empty set mysql> select * from goods$ +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 12 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 3 rows in set ------------------------------------修改订单update触发器----------------------------------------- 修改订单公式:update goods set num=num+old.much-new.much where id=old.gid; 关键部分:新数量等=本身数量+被修改的旧数量-新产生的数量(完全数学逻辑),id不变 create trigger tg4 after update on indent for each row begin update goods set num=num+old.much-new.much where id=old.gid; end $ ------------------------- mysql> select * from goods$ +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 7 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 3 rows in set mysql> select * from indent $ +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 2 | 1 | 5 | +-----+-----+------+ 1 row in set mysql> update indent set much=10 where oid=2$ Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from goods$ +----+-------------+-----+ | id | name | num | +----+-------------+-----+ | 1 | 三星手机 | 2 | | 2 | ipad电脑 | 19 | | 3 | 摩托罗拉mp3 | 35 | +----+-------------+-----+ 3 rows in set mysql> select * from indent$ +-----+-----+------+ | oid | gid | much | +-----+-----+------+ | 2 | 1 | 10 | +-----+-----+------+ 1 row in set ------------------------------------------- 触发器基础完成! 快速清空表:truncate [表名] 修改mysql的结束符:delimiter $; 显示触发器:show triggers 删除触发器:drop trigger [触发器名称] 创建触发器: create trigger [触发器名称] after [触发行为/insert/update/delete] on [监视对象/某张表] for each row #固定写法 begin sql语句; end $ 注意:一个触发器只能对应某张表的某一个行为!不能多个触发器来监视某一张表的同一个行为!