您现在的位置是:首页 >技术交流 >第十七章:触发器网站首页技术交流

第十七章:触发器

小王超会敲代码 2024-09-13 00:01:04
简介第十七章:触发器

第十七章:触发器

17.1:触发器概述

MySQL从5.0.2版本开始支持触发器。MySQL的触发器和存储过程一样,都是嵌入到MySQL服务器的一段程序。

​ 触发器是由事件来触发某个操作,这些事件包括INSERTUPDATEDELETE事件。所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句时候,就相当于事件发生了,就会自动激发触发器执行相应的操作。

17.2:触发器的创建

  1. 创建触发器语法

    CREATE TRIGGER 触发器名称
    {BEFORE | AFTER} { INSERT | UPDATE | DELETE} ON 表名
    FOR EACH ROW
    触发器执行的语句块;
    
    • 表名:触发器监控的对象。
    • BEFORE | AFTER:表示触发的时间。BEFORE表示在事件之前触发;AFTER表示在事件之后触发。
    • INSERT | UPDATE | DELETE:表示触发的事件。
      1. INSERT表示插入记录时触发。
      2. UPDATE表示更新记录时触发。
      3. DELETE表示删除记录时触发。
    • 触发器执行的语句块:可以是单条SQL语句,也可以是由BEGIN ... END结构组成的复合语句块。
  2. 举例

    #举例1:创建名称为before_insert_test_tri的触发器,
    #向test_trigger数据表插入数据之前,向test_trigger_log数据表中插入before_insert的日志信息。
    DELIMITER //
    CREATE TRIGGER before_insert_test_tri
    BEFORE INSERT ON test_trigger
    FOR EACH ROW
    BEGIN
    	INSERT INTO test_trigger_log(t_log)
    	VALUES('before insert...');
    END //
    DELIMITER;
    #测试
    INSERT INTO test_trigger(t_note)
    VALUES('Tom....');
    SELECT * FROM test_trigger; #新增了一条数据
    SELECT * FROM test_trigger_log; #新增了一条数据
    
    #举例2:定义触发器“salary_check_trigger”,基于员工表“employees”的INSERT事件,
    #在INSERT之前检查将要添加的新员工薪资是否大于他领导的薪资,
    #如果大于领导薪资,则报sqlstate_value为'HY000'的错误,从而使得添加失败。
    DELIMITER //
    CREATE TRIGGER salary_check_trigger
    BEFORE INSERT ON employees
    FOR EACH ROW
    BEGIN
    	#查询到要添加的数据的manager的薪资
    	DECLARE mgr_sal DOUBLE;
    	# 赋值
    	SELECT salary INTO mgr_sal FROM employees WHERE employee_id = NEW.manager_id;
    	
    	IF NEW.salary > mgr_sal
    		THEN SIGNAL SQLSTATE 'HY000' SET message_text = '薪资高于领导薪资错误';
    	END IF;
    END //
    DELIMITER;
    #测试
    #添加成功:依然触发了触发器salary_check_trigger的执行
    INSERT INTO employees(employee_id, last_name, email, hire_date, job_id, salary, manager_id)
    VALUES(301, 'Tom1', 'tom@126.com', CURDATE(), 'AD_VP', 8000, 103);
    #添加失败
    INSERT INTO employees(employee_id, last_name, email, hire_date, job_id, salary, manager_id)
    VALUES(30, 'Tom', 'tom@126.com', CURDATE(), 'AD_VP', 10000, 103);
    

17.3:查看、删除触发器

  1. 查看触发器

    查看触发器是查看数据库中已经存在的触发器的定义、状态和语法信息等。

    • 方式一:查看当前数据库的所有触发器的定义

      SHOW TRIGGERS;
      
    • 方式二:查看当前数据库中某个触发器的定义

      SHOW CREATE TRIGGER 触发器名;
      
    • 方式三:从系统库information_schemaTRIGGERS表中查询触发器的信息

      SELECT * FROM information_schema.TRIGGERS;
      
  2. 删除触发器

    触发器也是数据库对象,删除触发器也用DROP语句,语法格式如下:

    DROP TRIGGER IF EXISTS 触发器名称;
    

17.4:触发器的优缺点

  1. 优点

    • 触发器可以确保数据的完整性
    • 触发器可以帮助我们记录操作日志
    • 触发器还可以用在操作数据前,对数据进行合法性检查
  2. 缺点

    • 触发器最大的一个问题就是可读性差

      因为触发器存储在数据库中,并且由事件驱动,这就意味着触发器有可能不受应用层的控制。这对系统维护是非常有挑战的。

    • 相关数据的变更,可能会导致触发器出错

      ​ 特别是数据表结构的变更,都可能会导致触发器出错,进而影响操作的正常运行。这些都会由于触发器本身的隐蔽性,影响到应用中错误原因排查的效率。

  3. 注意点

    ​ 如果在子表中定义了外键约束,并且外键指定了ON UPDATE / DELETE CASCADE / SET NULL子句,此时修改父表被引用的键值或删除父表被引用的记录行时,也会引起子表的修改和删除操作,此时基于子表的UPDATEDELETE语句定义的触发器并不会被激活。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。