MySQL _ 12 _ 触发器

本文介绍了MySQL触发器的概念及作用,详细讲解了如何创建单条和多条执行语句的触发器,并提供了查看和删除触发器的方法。通过示例展示了触发器在数据更新、插入时的自动操作,强调了使用触发器时的注意事项,如每个表每个事件只能有一个触发器。

触发器(trigger)是一个特殊的存储过程,不同的是,执行存储过程要使用CALL语句来调用,而触发器的执行不需要使用CALL语句来调用,也不需要手工启动,只要当一个预定义的事件发生的时候,就会被MySQL自动调用。

触发器可以查询其他表,而且可以包含复杂的SQL语句。它们主要用于满足复杂的业务规则或要求。例如,可以根据客户当前的账户状态控制是否允许插入新订单。本节将介绍如何创建触发器。


01 _ 创建触发器

CREATE TRIGGER `trigger_name` `trigger_time` `trigger_event`
ON `tbl_name` FOR EACH ROW `trigger_stmt`

------------------------------------------------------

`trigger_name` -- 表示触发器名称,用户自行指定
`trigger_time` -- 表示触发时机,可以指定为before或after
`trigger_event` -- 表示触发事件,包括INSERT、UPDATE和DELETE
`tbl_name` -- 表示建立触发器的表名,即在哪张表上建立触发器
`trigger_stmt` -- 是触发器执行语句,可以是一条语句。
               -- 也可以用BEGIN和END作为开始和结束,中间包含多条语句。

创建一个单执行语句的触发器

  1. 创建一个account表,表中有两个字段,分别为acct_num字段(定义为int类型)和amount字段(定义成浮点类型)
CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
  1. 创建一个名为ins_sum的触发器,触发的条件是向数据表account插入数据之前,对新插入的amount字段值进行求和计算。
Create Trigger ins_sum Before Insert
On myaccount For Each Row Set @sum = @sum + NEW.amount;
  1. 插入数据,测试。
mysql> Set @sum = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> Insert Into account values(1,1.00),(2,2.00);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> Select @sum;
+------+
| @sum |
+------+
| 3.00 |
+------+
1 row in set (0.00 sec)

mysql>

创建有多个执行语句的触发器

  1. 创建几个表
Create Table test1(a1 Int);
Create Table test2(a2 Int);
Create Table test3(a3 Int Not Null Auto_Increment Primary Key);
Create Table test4(
    a4 Int Not Null Auto_Increment Primary Key,
    b4 Int Default 0
);
  1. 创建存储过程
Delimiter //
Create Trigger testref Before Insert On test1 For Each Row
Begin
	Insert Into test2 Set a2 = NEW.a1;
	Delete From test3 Where a3 = NEW.a1;
	Update test4 Set b4 = b4 + 1 Where a4 = NEW.a1;
End;
Delimiter ;
  1. 插入,测试。
Insert Into test3 (a3) Values
    (NULL),(NULL),(NULL),(NULL),(NULL),
    (NULL),(NULL),(NULL),(NULL),(NULL);

Insert Into test4 (a4) Values
	(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);

--------------------------------------------

mysql> Insert Into test1 Values(1),(3),(1),(7),(1),(8),(4),(4);
Query OK, 8 rows affected (0.13 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> 
  1. 查看表数据
mysql> Select * From test1;
+------+
| a1   |
+------+
|    1 |
|    3 |
|    1 |
|    7 |
|    1 |
|    8 |
|    4 |
|    4 |
+------+
8 rows in set (0.00 sec)

mysql> Select * From test2;
+------+
| a2   |
+------+
|    1 |
|    3 |
|    1 |
|    7 |
|    1 |
|    8 |
|    4 |
|    4 |
+------+
8 rows in set (0.01 sec)

mysql> Select * From test3;
+----+
| a3 |
+----+
|  2 |
|  5 |
|  6 |
|  9 |
| 10 |
+----+
5 rows in set (0.00 sec)

mysql> Select * From test4;
+----+------+
| a4 | b4   |
+----+------+
|  1 |    3 |
|  2 |    0 |
|  3 |    1 |
|  4 |    2 |
|  5 |    0 |
|  6 |    0 |
|  7 |    1 |
|  8 |    1 |
|  9 |    0 |
| 10 |    0 |
+----+------+
10 rows in set (0.00 sec)

mysql>

INSERT触发了触发器,向test2中插入了test1中的值,删除了test3中相同的内容,同时更新了test4中的b4,即与插入的值相同的个数。



02 _ 查看触发器

查看触发器是指查看数据库中已存在的触发器的定义、状态和语法信息等。可以通过 SHOW TRIGGERS 和在 triggers表 中查看已经创建的触发器。

SHOW TRIGGERS

Show Triggers;

SHOW TRIGGERS 语句查看当前创建的所有触发器信息,在触发器较少的情况下,使用该语句会很方便。如果要查看特定触发器的信息,可以直接从 information_schema数据库 中的 triggers表 中查找。

栗子:

mysql> Show Triggers\G
*************************** 1. row ***************************
             Trigger: ins_sum
               Event: INSERT
               Table: account
           Statement: Set @sum = @sum + NEW.amount
              Timing: BEFORE
             Created: 2021-08-07 17:03:15.76
            sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
             Definer: root@localhost
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
  Database Collation: utf8_general_ci
*************************** 2. row ***************************
             Trigger: testref
               Event: INSERT
               Table: test1
           Statement: Begin
        Insert Into test2 Set a2 = NEW.a1;
        Delete From test3 Where a3 = NEW.a1;
        Update test4 Set b4 = b4 + 1 Where a4 = NEW.a1;
End
              Timing: BEFORE
             Created: 2021-08-07 17:37:11.73
            sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
             Definer: root@localhost
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
  Database Collation: utf8_general_ci
2 rows in set (0.00 sec)

triggers

在MySQL中,所有触发器的定义都存在Information_Schema数据库的 Triggers 表格中,可以通过查询命令SELECT查看

Select * From information_schema.`TRIGGERS` Where condition;

栗子:

mysql> Select * From information_schema.`TRIGGERS` 
     > Where TRIGGERS.TRIGGER_NAME = 'testref'\G
*************************** 1. row ***************************
           TRIGGER_CATALOG: def
            TRIGGER_SCHEMA: mysql80_demo12
              TRIGGER_NAME: testref
        EVENT_MANIPULATION: INSERT
      EVENT_OBJECT_CATALOG: def
       EVENT_OBJECT_SCHEMA: mysql80_demo12
        EVENT_OBJECT_TABLE: test1
              ACTION_ORDER: 1
          ACTION_CONDITION: NULL
          ACTION_STATEMENT: Begin
        Insert Into test2 Set a2 = NEW.a1;
        Delete From test3 Where a3 = NEW.a1;
        Update test4 Set b4 = b4 + 1 Where a4 = NEW.a1;
End
        ACTION_ORIENTATION: ROW
             ACTION_TIMING: BEFORE
ACTION_REFERENCE_OLD_TABLE: NULL
ACTION_REFERENCE_NEW_TABLE: NULL
  ACTION_REFERENCE_OLD_ROW: OLD
  ACTION_REFERENCE_NEW_ROW: NEW
                   CREATED: 2021-08-07 17:37:11.73
                  SQL_MODE: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
                   DEFINER: root@localhost
      CHARACTER_SET_CLIENT: utf8mb4
      COLLATION_CONNECTION: utf8mb4_0900_ai_ci
        DATABASE_COLLATION: utf8_general_ci
1 row in set (0.00 sec)

mysql> 




03 _ 触发器的使用

触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。在某些触发程序的用法中,可用于检查插入到表中的值,或对更新涉及的值进行计算。

触发程序与表相关,当对表执行INSERT、DELETE或UPDATE语句时,将激活触发程序。可以将触发程序设置为在执行语句之前或之后激活。

栗子:创建一个在 account表 插入记录之后更新myevent数据表的触发器。

  1. account 表 与 myevent 表
Create Table account (acct_num INT, amount DECIMAL(10,2));
Create Table myevent (id Int, evt_name VarChar(20));
  1. 创建 trig_insert 触发器
Create Trigger trig_insert After Insert On account
For Each Row Insert Into myevent Values(2,'after insert');
  1. 给表 account 插入数据,查看表 myevent。
mysql> Insert Into account values(3,3.00),(4,4.00),(5,5.00);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> Select * From myevent;
+------+--------------+
| id   | evt_name     |
+------+--------------+
|    2 | after insert |
|    2 | after insert |
|    2 | after insert |
+------+--------------+
3 rows in set (0.00 sec)

mysql>




04 _ 删除触发器

DROP TRIGGER [schema_name.]trigger_name

----------------------------------------
`schema_name` 表示数据库名称,是可选的。如果省略了schema,将从当前数据库中舍弃触发程序
`trigger_name`  要删除的触发器的名称




05 _ 使用触发器的注意事项

  1. 对于相同的表,相同的事件只能创建一个触发器。

    即,表 a 如果创建了一个 Before Insert 触发器,那么再创建Before Insert 便会报错。此时只能创建 AFTER INSERT 或者 [Before | After] [Update | Delete] 触发器。

  2. 需求变化时,及时删除不再需要的触发器,以免旧的触发器影响新的数据完整性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值