触发器:触发器是MySQL响应DELETE、INSERT、UPDATE任意语句而自动执行的一条MySQL语句,其通常位于BEGIN和END语句之间的一组语句。
一、创建触发器
在创建触发器时,需要给出以下4条信息:
1.唯一的触发器名;
2.触发器关联的表;
3.触发器应该响应的活动(DELETE、INSERT或UPDATE);
4.触发器何时执行(AFTER或BEFORE)。
触发器是用CREATE TRIGGER语句来创建的,下面为一个简单的例子:
CREATE TRIGGER newproduct AFTER INSERT ON products
FOR EACH ROW SELECT 'Product added';
该例子中通过CREATE TRIGGER语句创建名为newproduct的触发器,其作用是打印Product added。AFTER表示此触发器在INSERT执行成功后执行。这个触发器还指定FOR EACH ROW,即在插入每一行时都会执行此触发器。
二、删除触发器
DROP TRIGGER语句用于删除一个触发器,如下所示:
DROP TRIGGER newproduct;
注意:触发器不能更新或覆盖,为了修改一个触发器,必须先删除它,然后再重新创建。
三、INSERT触发器
INSERT触发器可以在INSERT之前或之后执行,需要注意一下几点:
1.在INSERT触发器代码内,可以引用一个名为NEW的虚拟表,访问被插入的行;
2.在BEFORE INSERT触发器中,NEW中的值也可以被更新(运行更改被插入的值);
3.对于AUTO_INCREMENT列,NEW在INSERT之前为0,在INSERT之后为新的自动生成值。
下面为INSERT触发器的一个例子:
CREATE TRIGGER neworder AFTER INSERT ON orders
FOR EACH ROW
INSERT INTO orders_bak(order_num, order_date, cust_id)
VALUES(NEW.order_num, NEW.order_date, NEW.cust_id);
该触发器在INSERT插入一行数据之后,将新插入的cust_id插入到orders_bak表中。下面对该触发器进行验证:
INSERT INTO orders(order_date, cust_id)
VALUES(NOW(), 10002);
然后使用下面指令来查看表orders_bak的内容:
SELECT *
FROM orders_bak;
执行结果:
四、DELETE触发器
DELETE触发器在DELETE语句执行之前或之后执行,需要注意以下两点:
1.在DELETE代码中可以引用一个OLD的虚拟表,访问被删除的行;
2.OLD中的值全部是只读的,不能更新。
下面例子演示使用OLD保存将要被删除的行到一个存档中:
CREATE TRIGGER deleteorder
BEFORE DELETE ON orders
FOR EACH ROW
INSERT INTO archive_orders(order_num, order_date, cust_id)
VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);
下面删除刚才插入的那行数据:
DELETE FROM orders
WHERE cust_id = 10002;
再使用下面指令查看表archive_orders的内容:
SELECT *
FROM archive_orders;
执行结果:
五、UPDATE触发器
UPDATE触发器在UPDATE语句之前或之后执行,需要注意一下几点:
1.在UPDATE触发器代码中可以引用一个OLD的虚拟表访问更新前的数据,引用NEW的虚拟表访问更新后的值;
2.在BEFORE UPDATE触发器中,NEW中的值可能也被更新;
3.OLD中的值全部都是只读的。
下面例子保证州名缩写总是大写:
CREATE TRIGGER updatevendor
BEFORE UPDATE ON vendors
FOR EACH ROW
SET NEW.vend_state = UPPER(NEW.vend_state);