MySQL必知必会-22MySQL触发器

触发器
MySQL 5中增加了对触发器的支持。

触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句)
DELETE
INSERT
UPDATE
其他MySQL语句不支持触发器

创建触发器
在创建触发器时,需要给出4条信息:
唯一的触发器名
触发器关联的表
触发器应该响应的活动(DELETE、INSERT或UPDATE)
触发器何时执行(处理之前或之后)

在MySQL5中,触发器名必须在每个表中唯一,但以后的MySQL版本可能会使命名规则更为严格,所以现在最好是在数据库范围内使用唯一的触发器名。

原书中的例子,以不能使用,如下
 
    
  1. CREATE TRIGGER newproduct AFTER INSERT ON products
  2. FOR EACH ROW SELECT 'Product added';
会返回错误信息:1415 - Not allowed to return a result set from a trigger
所以改成如下:
 
    
  1. CREATE TRIGGER newproduct AFTER INSERT ON products
  2. FOR EACH ROW SET @msg = 'Product added';
调用两个SQL语句:
 
    
  1. INSERT INTO products (
  2. prod_id,
  3. vend_id,
  4. prod_name,
  5. prod_price,
  6. prod_desc
  7. )
  8. VALUES
  9. (
  10. 'TNT3',
  11. 1003,
  12. 'TNT (6 sticks)',
  13. 12,
  14. 'TNT, red, pack of 10 sticks'
  15. );
  16. SELECT @msg;
@msg来自于TRIGGER中定义的@msg

仅支持表
只有表才支持触发器,视图不支持(临时表也不支持)
触发器按每个表每个时间每次地定义,每个表每个事件每次只允许一个触发器。
因此,每个表最多支持6个触发器(每条INSERT,UPDATE,DELETE的之前和之后)
单一触发器不能与多个事件或多个表关联,所以需要一个INSERT和UPDATE操作执行的触发器,则定义两个触发器。

触发器失败
如果BEFORE触发器失败,则MySQL将不执行请求的操作。此外,如果BEFOR触发器或语句本身失败,MySQL将不执行AFTER触发器(如果有的话)

删除触发器
 
    
  1. DROP TRIGGER newproduct;
触发器不能更新或覆盖。为了修改一个触发器,必须先删除它,然后再重新创建。

使用触发器

INSERT触发器
在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行。
在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改被插入的值)
对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0,在INSERT执行之后包含新的自动生产值

原文范例,不适用用
 
    
  1. CREATE TRIGGER neworder AFTER INSERT ON orders
  2. FOR EACH ROW SELECT NEW.order_num;
改成:
 
     
  1. CREATE TRIGGER neworder AFTER INSERT ON orders
  2. FOR EACH ROW SET @num = NEW.order_num;

DELETE触发器
在DELETE触发器代码内,可以引用一个名为OLD的虚拟表,访问被删除的行。
OLD中的值全部都是只读的,不能更新。
 
    
  1. CREATE TRIGGER deleteorder BEFORE DELETE ON orders FOR EACH ROW
  2. BEGIN
  3. INSERT INTO archive_orders (
  4. order_num,
  5. order_date,
  6. cust_id
  7. )
  8. VALUES
  9. (
  10. OLD.order_num,
  11. OLD.order_date,
  12. OLD.cust_id
  13. );
  14. END;
实际使用这个例子,需要用与orders相同的列创建一个名为archive_orders的表。
使用BEGIN END块的好处是触发器能容纳多条SQL语句(在BEGIN END块中一条挨着一条)

UPDATE触发器
在UPDATE触发器代码中,可以引用一个名为OLD的虚拟表访问以前(UPDATE语句前)的值,引用一个名为NEW的虚拟表访问新更新的值。
在BEFORE UPDATE触发器中,NEW中的值可能也被更新(允许更改将要用于UPDATE语句中的值)
OLD中的值全部都是只读的,不能更新。
 
     
  1. CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors FOR EACH ROW
  2. SET NEW.vend_state = Upper(NEW.vend_state);
每次更新一个行时,NEW.vend_state中的值(将用来更新表行的值)都用Upper(NEW.vend_state)替换

MySQL触发器不支持CALL语句,这表示不能从触发器内调用存储过程。所需要的存储过程代码需要复制到触发器内。

你可能感兴趣的:(MySQL)