• MySQL Crash Course #17# Chapter 25. 触发器(Trigger)


    推荐看这篇 mysql 利用触发器(Trigger)让代码更简单

    以及 23.3.1 Trigger Syntax and Examples

     感觉有点像 Spring 里的 AOP

    我们为什么需要触发器? -- 因为我们希望当某件事情发生的时候另外一些事情自动发生。。

    例如 在向某张表插入数据的时候,同时向另外一张表插入数据。

    “向某张表插入数据” 就是事件(导火线),而“向另外一张表插入数据” 就是我们希望自动发生的事情(被触发的事情)。

    可是为什么不自己手动“ 先向某表插入数据,再向另外一张表插入数据”呢?

    个人觉得,有两个理由促使我们这么做:

    1. 实现某种业务逻辑,就像下了订单一定要减库存对吧? 但是这个活是上层应用程序做还是数据库做是个问题。
    2. 关注点分离。触发事件可以是一些琐碎、业务无关的安全性检查之类的,这个概念可以参考 Spring AOP

    下面 COPY 几个 demo 备用。

    首先是查看已存在的触发器:

    SELECT * FROM information_schema.`TRIGGERS`;

    删除已经存在的触发器:

    DROP TRIGGER newproduct;

    创建一个简单的触发器:

    CREATE TRIGGER newproduct AFTER INSERT ON products
    FOR EACH ROW SELECT 'Product added';

    -- -  每当向 products 插入数据的时候都执行 SELECT 'Product added' ,// 原话打印

    - - -- FOR EACH ROW 对于插入的每一条记录都这么做

    --- --  PS. 触发器只能创建在实表上,不能创建在虚表上(视图)

    -- - - - 每张表至多支持 6 个触发器 AFTER BEFORE 2 * 3 UPDATE DELETE INSERT = 6      PS. 这个有错。

    -  ---我尝试了一下居然运行不出来 。。 。 所以,以上规则可能在新版本有变化。。

    mysql> CREATE TRIGGER newproduct AFTER INSERT ON products
        -> FOR EACH ROW SELECT 'Product added';
    ERROR 1415 (0A000): Not allowed to return a result set from a trigger

     关于触发器的几个注意点:

    1. 触发器不能被覆盖 override ,要修改的话,只能先删除旧的、再创建一个新的。
    2. 在 BEFORE触发器 → SQL语句 → AFTER 触发器这个执行流程中,任何一步出现错误都将不再往下执行。

    关于 OLD 和 NEW 关键词

    Within the trigger body, the OLD and NEW keywords enable you to access columns in the rows affected by a trigger. OLDand NEW are MySQL extensions to triggers; they are not case-sensitive.

    In an INSERT trigger, only NEW.col_name can be used; there is no old row. In a DELETE trigger, only OLD.col_name can be used; there is no new row. In an UPDATE trigger, you can use OLD.col_name to refer to the columns of a row before it is updated and NEW.col_name to refer to the columns of the row after it is updated.

    A column named with OLD is read only. You can refer to it (if you have the SELECT privilege), but not modify it. You can refer to a column named with NEW if you have the SELECT privilege for it. In a BEFORE trigger, you can also change its value with SET NEW.col_name = value if you have the UPDATE privilege for it. This means you can use a trigger to modify the values to be inserted into a new row or used to update a row. (Such a SET statement has no effect in an AFTERtrigger because the row change will have already occurred.)

    In a BEFORE trigger, the NEW value for an AUTO_INCREMENT column is 0, not the sequence number that is generated automatically when the new row actually is inserted.

    触发更多语句

    By using the BEGIN ... END construct, you can define a trigger that executes multiple statements.

    mysql> delimiter //
    mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account
           FOR EACH ROW
           BEGIN
               IF NEW.amount < 0 THEN
                   SET NEW.amount = 0;
               ELSEIF NEW.amount > 100 THEN
                   SET NEW.amount = 100;
               END IF;
           END;//
    mysql> delimiter ;

    demo

    DROP TRIGGER IF EXISTS afterDeleteStudent;
    DELIMITER //
    CREATE TRIGGER afterDeleteStudent
    AFTER DELETE ON stu
    FOR EACH ROW
    BEGIN
        DELETE FROM SC WHERE SC.stu_id = OLD.id;
    END // 
    DELIMITER ;
  • 相关阅读:
    RxJava Android(RxAndroid) 开发全家桶
    Android Retrofit RxJava实现缓存
    Android Touch事件传递机制详解 下
    Android Touch事件传递机制详解 上
    Android Framework 记录之二
    XMind 8 Update 7 Pro 激活码
    leetcode 2-> Add Two Numbers
    leetcode 1 -> Two Sum
    leetcode 3-> Longest Substring Without Repeating Characters
    Python enumerate() 函数
  • 原文地址:https://www.cnblogs.com/xkxf/p/8919828.html
Copyright © 2020-2023  润新知