MySQL 8.0——触发器
触发器1、创建触发器1.1、创建只有一个执行语句的触发器1.2、创建有多个执行语句的触发器2、查看触发器2.1、利用SHOW TRIGGERS语句查看触发器信息2.2、在triggers表中查看触发器信息3、触发器的使用4、删除触发器5、综合案例6、常见问题6.1、使用触发器时要特别注意的事项6.2、及时删除不再需要的触发器MySQL的触发器和存储过程一样都是嵌入到MySQL的一段程序。触发器是由事件来触发某个操作这些事件包括INSERT、UPDATAE和DELETE语句。如果定义了触发程序当数据库执行这些语句的时候就会激发触发器执行相应的操作触发程序是与表有关的命名数据库对象当表上出现特定事件时将激活该对象。1、创建触发器触发器trigger是一个特殊的存储过程不同的是执行存储过程要使用CALL语句来调用而触发器的执行不需要使用CALL语句来调用也不需要手工启动只要当一个预定义的事件发生的时候就会被MySQL自动调用。比如当对fruits表进行操作INSERT、DELETE或UPDATE时就会激活它执行。触发器可以查询其他表而且可以包含复杂的SQL语句。它们主要用于满足复杂的业务规则或要求。例如可以根据客户当前的账户状态控制是否允许插入新订单。1.1、创建只有一个执行语句的触发器创建一个触发器的语法如下CREATETRIGGERtrigger_name trigger_time trigger_eventONtbl_nameFOR EACH ROWtrigger_stmttrigger_name表示触发器名称用户自行指定trigger_time表示触发时机可以指定为before或aftertrigger_event表示触发事件包括INSERT、UPDATE和DELETEtbl_name表示建立触发器的表名即在哪张表上建立触发器trigger_stmt是触发器执行语句。创建一个单执行语句的触发器代码如下createtableaccount(acct_numint,amountdecimal(10,2));createtriggerins_sum beforeinsertonaccountfor each rowsetsumsumNEW.amount;首先创建一个account表表中有两个字段分别为acct_num字段定义为int类型和amount字段定义成浮点类型其次创建一个名为ins_sum的触发器触发的条件是向数据表account插入数据之前对新插入的amount字段值进行求和计算。setsum0;insertintoaccountvalues(1,1.00),(2,2.00);select*fromaccount;------------------|acct_num|amount|------------------|1|1.00||2|2.00|------------------selectsum;------|sum|------|3.00|------首先创建一个account表在向表account插入数据之前计算所有新插入的account表的amount值之和触发器的名称为ins_sum条件是在向表插入数据之前触发。1.2、创建有多个执行语句的触发器创建多个执行语句的触发器的语法如下CREATETRIGGERtrigger_name trigger_time trigger_eventONtb1_nameFOR EACH ROWBEGIN语句执行列表ENDtrigger_name标识触发器的名称用户自行指定trigger_time标识触发时机可以指定为before或aftertrigger_event标识触发事件包括INSERT、UPDATE和DELETEtbl_name标识建立触发器的表名即在哪张表上建立触发器触发器程序可以使用BEGIN和END作为开始和结束中间包含多条语句。创建一个包含多个执行语句的触发器代码如下createtabletest1(a1int);createtabletest2(a2int);createtabletest3(a3intnotnullauto_incrementprimarykey);createtabletest4(a4intnotnullauto_incrementprimarykey,b4intdefault0);delimiter$$createtriggertestref beforeinsertontest1for each rowbegininsertintotest2seta2NEW.a1;deletefromtest3wherea3NEW.a1;updatetest4setb4b41wherea4NEW.a1;end$$delimiter;insertintotest3(a3)values(null),(null),(null),(null),(null),(null),(null),(null);insertintotest4(a4)values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);上面的代码创建了一个名为testref的触发器。这个触发器的触发条件是在向表test1插入数据前执行触发器的语句具体执行的代码如下insertintotest1values(1),(3),(1),(7),(1),(8),(4),(4);4个表中的数据如下select*fromtest1;----|a1|----|1||3||1||7||1||8||4||4|----select*fromtest2;----|a2|----|1||3||1||7||1||8||4||4|----select*fromtest3;----|a3|----|2||5||6|----select*fromtest4;--------|a4|b4|--------|1|3||2|0||3|1||4|2||5|0||6|0||7|1||8|1||9|0||10|0|--------执行结果显示在向表test1插入记录的时候test2、test3、test4都发生了变化。从这个例子看INSERT触发了触发器向test2中插入了test1中的值删除了test3中相同的内容同时更新了test4中的b4即与插入的值相同的个数。2、查看触发器查看触发器是指查看数据库中已存在的触发器的定义、状态和语法信息等。可以通过命令来查看已经创建的触发器。两种查看触发器的方法分别是SHOWTRIGGERS和在triggers表中查看触发器信息。2.1、利用SHOW TRIGGERS语句查看触发器信息通过SHOW TRIGGERS查看触发器的语句如下SHOWTRIGGERS;通过SHOW TRIGGERS命令查看一个触发器代码如下showtriggers;***************************[1.row]***************************Trigger|ins_sum Event|INSERTTable|account Statement|setsumsumNEW.amount Timing|BEFORE Created|2026-06-2521:50:31.090000***************************[1.row]***************************Trigger|ins_sum Event|INSERTTable|account Statement|setsumsumNEW.amount Timing|BEFORE Created|2026-06-2521:50:31.090000***************************[1.row]***************************Trigger|ins_sum Event|INSERTTable|account Statement|setsumsumNEW.amount Timing|BEFORE Created|2026-06-2521:50:31.090000sql_mode|ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTIONDefiner|root%character_set_client|utf8mb4 collation_connection|utf8mb4_0900_ai_ciDatabaseCollation|utf8mb3_general_ci***************************[2.row]***************************Trigger|testref Event|INSERTTable|test1 Statement|begininsertintotest2seta2NEW.a1;deletefromtest3wherea3NEW.a1;updatetest4setb4b41wherea4NEW.a1;endTiming|BEFORE Created|2026-06-2521:58:25.100000sql_mode|ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTIONDefiner|root%character_set_client|utf8mb4 collation_connection|utf8mb4_0900_ai_ciDatabaseCollation|utf8mb3_general_ci创建一个简单的触发器名称为trig_update每次向account表更新数据之后都会向名称为myevent的数据表中插入一条记录数据表myevent定义如下createtablemyevent(idint(11)defaultnull,evt_namechar(20)defaultnull);创建触发器的执行代码如下createtriggertrig_updateafterupdateonaccountfor each rowinsertintomyeventvalues(1,after update);使用SHOW TRIGGERS命令查看触发器showtriggers \G;***************************[1.row]***************************Trigger|ins_sum Event|INSERTTable|account Statement|setsumsumNEW.amount Timing|BEFORE Created|2026-06-2521:50:31.090000sql_mode|ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTIONDefiner|root%character_set_client|utf8mb4 collation_connection|utf8mb4_0900_ai_ciDatabaseCollation|utf8mb3_general_ci***************************[2.row]***************************Trigger|trig_update Event|UPDATETable|account Statement|insertintomyeventvalues(1,after update)Timing|AFTERCreated|2026-06-2522:10:09.490000sql_mode|ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTIONDefiner|root%character_set_client|utf8mb4Trigger表示触发器的名称在这里两个触发器的名称分别为ins_sum和trig_updateEvent表示激活触发器的事件这里的两个触发事件为插入操作INSERT和更新操作UPDATETable表示激活触发器的操作对象表这里都为account表Timing表示触发器触发的时间分别为插入操作之前BEFORE和更新操作之后AFTERStatement表示触发器执行的操作还有一些其他信息比如sql的模式、触发器的定义账户和字符集等2.2、在triggers表中查看触发器信息在MySQL中所有触发器的定义都存在INFORMATION_SCHEMA数据库的TRIGGERS表格中可以通过查询命令SELECT查看具体的语法如下SELECT*FROMINFORMATION_SCHEMA.TRIGGERSWHEREcondition;通过SELECT命令查看触发器代码如下SELECT*FROMINFORMATION_SCHEMA.TRIGGERSWHERETRIGGER_NAMEtrig_update\G;***************************[1.row]***************************TRIGGER_CATALOG|def TRIGGER_SCHEMA|test_db TRIGGER_NAME|trig_update EVENT_MANIPULATION|UPDATEEVENT_OBJECT_CATALOG|def EVENT_OBJECT_SCHEMA|test_db EVENT_OBJECT_TABLE|account ACTION_ORDER|1ACTION_CONDITION|nullACTION_STATEMENT|insertintomyeventvalues(1,after update)ACTION_ORIENTATION|ROWACTION_TIMING|AFTERACTION_REFERENCE_OLD_TABLE|nullACTION_REFERENCE_NEW_TABLE|nullACTION_REFERENCE_OLD_ROW|OLD ACTION_REFERENCE_NEW_ROW|NEW CREATED|2026-06-2522:10:09.490000SQL_MODE|ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTIONDEFINER|root%CHARACTER_SET_CLIENT|utf8mb4 COLLATION_CONNECTION|utf8mb4_0900_ai_ci DATABASE_COLLATION|utf8mb3_general_ci从上面的执行结果可以得知TRIGGER_SCHEMA表示触发器所在的数据库TRIGGER_NAME后面是触发器的名称EVENT_OBJECT_TABLE表示在哪个数据表上触发ACTION_STATEMENT表示触发器触发的时候执行的具体操作ACTION_ORIENTATION是ROW表示在每条记录上都触发ACTION_TIMING表示触发的时刻是AFTER剩下的是和系统相关的信息。也可以不指定触发器名称这样将查看所有的触发器命令如下SELECT*FROMINFORMATION_SCHEMA.TRIGGERS \G这个命令会显示TRIGGERS表中所有的触发器信息。3、触发器的使用触发程序是与表有关的命名数据库对象当表上出现特定事件时将激活该对象。在某些触发程序的用法中可用于检查插入到表中的值或对更新涉及的值进行计算。触发程序与表相关当对表执行INSERT、DELETE或UPDATE语句时将激活触发程序。可以将触发程序设置为在执行语句之前或之后激活。例如可以在从表中删除每一行之前或在更新每一行之后激活触发程序。创建一个在account表插入记录之后更新myevent数据表的触发器代码如下createtriggertrig_insertafterinsertonaccountfor each rowinsertintomyeventvalues(2,after insert);上面的代码创建了一个trig_insert触发器在向表account插入数据之后会向表myevent插入一组数据代码执行如下insertintoaccountvalues(1,1.00),(2,2.00);select*frommyevent;------------------|id|evt_name|------------------|2|afterinsert||2|afterinsert|------------------从执行的结果来看创建了一个名称为trig_insert的触发器在向account插入记录之后进行触发执行的操作是向表myevent插入一条记录。4、删除触发器使用DROP TRIGGER语句可以删除MySQL中已经定义的触发器删除触发器语句的基本语法格式如下DROPTRIGGER[schema_name.]trigger_nameschema_name表示数据库名称是可选的。如果省略了schema将从当前数据库中舍弃触发程序trigger_name是要删除的触发器的名称;删除一个触发器代码如下droptriggertest_db.ins_sum;Query OK,0rowsaffectedTime:0.072s5、综合案例下面是创建触发器的实例每更新一次persons表的num字段后都要更新sales表对应的sum字段。其中persons表结构如表所示sales表结构如表所示persons表内容如表所示1. 创建一个业务统计表persons。创建一个业务统计表persons代码如下createtablepersons(namevarchar(40),numint);2. 创建一个销售额表sales。创建一个销售额表sales代码如下createtablesales(namevarchar(40),sumint);3. 创建一个触发器。创建一个触发器在更新过persons表的num字段后更新sales表的sum字段代码如下createtriggernum_sumafterinsertonpersonsfor each rowinsertintosalesvalues(NEW.name,7*NEW.num);4. 向persons表中插入记录。插入新的记录后更新销售额表。insertintopersonsvalues(xiaoxiao,20),(xiaohua,69);结果如下select*frompersons;---------------|name|num|---------------|xiaoxiao|20||xiaohua|69|---------------select*fromsales;---------------|name|sum|---------------|xiaoxiao|140||xiaohua|483|---------------从执行的结果来看在persons表插入记录之后num_sum触发器计算插入到persons表中的数据并将结果插入到sales表中相应的位置。6、常见问题6.1、使用触发器时要特别注意的事项使用触发器的时候需要注意对于相同的表相同的事件只能创建一个触发器比如对表account创建了一个BEFORE INSERT触发器那么如果对表account再次创建一个BEFORE INSERT触发器MySQL将会报错此时只可以在表account上创建AFTER INSERT或者BEFORE UPDATE类型的触发器。灵活地运用触发器将为操作省去很多麻烦。6.2、及时删除不再需要的触发器触发器定义之后每次执行触发事件都会激活触发器并执行触发器中的语句。如果需求发生变化而触发器没有进行相应的改变或者删除则触发器仍然会执行旧的语句从而会影响新的数据完整性。因此要将不再使用的触发器及时删除。