触发器,顾名思义,一触即发。
可以是在事件触发前,也可以是在世界触发后。
触发器创建语法:
官方定义:
CREATE [DEFINER = {user
| CURRENT_USER }] TRIGGERtrigger_name
trigger_time
trigger_event
ONtbl_name
FOR EACH ROWtrigger_body
看不懂,来个直观的:
create trigger triggerName
After/before insert/update/delete on 表名
for each row // 这句话固定的,mysql的触发器只支持行级别。
Begin
要执行的sql语句
End;
触发器只支持增删改这些操作。
这是商品表,num,代表库存。
mysql> select * from goods;
+----+--------+--------+-------+-----+
| id | name | cat_id | price | num |
+----+--------+--------+-------+-----+
| 1 | 苹果 | 1 | 4999 | 7 |
| 2 | nexus4 | 2 | 1999 | 5 |
| 3 | nokia | 3 | 1222 | 20 |
| 4 | 荣耀2 | 2 | 1888 | 5 |
| 5 | n93 | 3 | 2500 | 10 |
| 6 | 三星 | 2 | 3000 | 2 |
+----+--------+--------+-------+-----+
6 rows in set
这是订单表,num,所订购商品的数量。
mysql> select * from orders;
+----+---------+---------+-----+
| id | user | good_id | num |
+----+---------+---------+-----+
| 1 | gaotong | 1 | 1 |
+----+---------+---------+-----+
1 row in set
现在需要做的是,当对orders表进行增删改时,goods表的库存量会相应的变化。
由于我们早在trigger中执行sql语言,是以“ ; ”号结尾。要先更改下分隔符。
分别以new 和 old 来引用,新行和旧行。看例子就知道了:
mysql> delimiter $
mysql> create trigger onInsertTrigger
-> after insert on orders
-> for each row
-> Begin
-> update goods set num = num + new.num where id = new.good_id;
-> End$
Query OK, 0 rows affected
这样,在插入数据时,goods表的数据会相应的变化。
删除和更新,同理!
再来看下怎么用before。
现在希望在插入数据之前做一些判断,如果插入的订单数大于10,就是非法的。
要把订单数量改为5,然后再插入。
首先要删除原来的trigger。
mysql> drop trigger onInsertTrigger$
Query OK, 0 rows affected
mysql> create trigger checkInsert
-> before insert on orders
-> for each row
-> Begin
-> if new.num > 10 then
-> set new.num = 5;
-> end if;
-> update g set num = num-new.num where id = new.good_id;
-> end$
Query OK, 0 rows affected