MySQL必知必会-22MySQL触发器 客官°小女子只卖身不卖艺 2022-05-29 12:46 189阅读 0赞 # 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. `` 17. `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. `` 15. `` 16. `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语句,这表示不能从触发器内调用存储过程。所需要的存储过程代码需要复制到触发器内。
还没有评论,来说两句吧...