首页 > 数据库 > > 23.3 使用触发器
参考官方文档:
23.3 Using Triggers触发器是与表关联的数据库对象,并在表发生特定事件时激活。 触发器的一些用途是执行对要插入表中的值的检查,或者对更新中涉及的值执行计算。
触发器定义为在语句插入,更新或删除关联表中的行时激活。 这些行操作是触发事件。 例如,可以通过INSERT或LOAD DATA语句插入行,并为每个插入的行激活插入触发器。 可以将触发器设置为在触发事件之前或之后激活。 例如,您可以在插入表中的每一行之前或更新的每一行之后激活一个触发器。
重要
MySQL触发器仅针对对表所做的更改的SQL语句进行激活。 这包括对可更新视图的基础表的更改。 对于不将SQL语句传输到MySQL服务器的API所做的更改,触发器不会激活。 这意味着使用NDB API进行的更新不会激活触发器。
INFORMATION_SCHEMA或performance_schema表中的更改不会激活触发器。 这些表实际上是视图,触发器不允许在视图上。
以下部分描述了创建和删除触发器的语法,显示了如何使用它们的一些例子,并指出了如何获取触发器元数据。
23.3.1 触发器的语法和例子
下面是一个简单的示例,它将触发器与表关联起来,以激活INSERT操作。 触发器充当累加器,将插入到表的一列中的值相加。
mysql>CREATETABLEaccount(acct_numINT,amountDECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)
mysql>CREATETRIGGERins_sumBEFOREINSERTONaccountFOREACHROWSET@sum=@sum+NEW.amount;
Query OK, 0 rows affected (0.01 sec)
CREATE TRIGGER语句创建一个名为ins_sum的触发器,该触发器与帐户表关联。 它还包括指定触发器操作时间,触发事件以及触发器激活时要执行的操作的子句:
要使用触发器,请将accumulator变量设置为零,执行INSERT语句,然后查看变量后面的值:
mysql> SET @sum = 0;
mysql>INSERTINTOaccountVALUES(137,14.98),(141,1937.50),(97,-100.00);
mysql>SELECT@sumAS'Total amount inserted';
+-----------------------+
| Total amount inserted |
+-----------------------+
| 1852.48 |
+-----------------------+
在这种情况下,执行INSERT语句后@sum的值为14.98 + 1937.50 - 100或1852.48。
要销毁触发器,请使用DROP TRIGGER语句。 如果触发器不在默认方案中,则必须指定方案名称:
mysql>DROPTRIGGERtest.ins_sum;
如果删除表,则表的任何触发器也将被删除。
方案命名空间中存在触发器名称,这意味着所有触发器必须在方案中具有唯一名称。 不同方案中的触发器可以具有相同的名称。
从MySQL 5.7.2开始,可以为具有相同触发事件和激活时间的给定表定义多个触发器。 例如,您可以为表创建两个BEFORE UPDATE触发器。 默认情况下,具有相同触发事件和操作时间的触发器按创建顺序激活。 要影响触发器顺序,请在FOR EACH ROW之后指定一个指示FOLLOWS或PRECEDES的子句以及现有触发器的名称。 使用FOLLOWS,新触发器在现有触发器之后激活。 使用PRECEDES,新触发器在现有触发器之前激活。
在触发器主体中,OLD和NEW关键字使您可以访问受触发器影响的行中的列。 OLD和NEW是触发器的MySQL扩展; 它们不区分大小写。
在INSERT触发器中,只能使用NEW.col_name; 没有old行。 在DELETE触发器中,只能使用OLD.col_name; 没有新的行。 在UPDATE触发器中,您可以使用OLD.col_name在更新行之前引列,使用NEW.col_name在更新行之后引用列。
在BEFORE触发器中,AUTO_INCREMENT列的NEW值为0,而不是实际插入新行时自动生成的序列号。
通过使用BEGIN ... END构造,您可以定义执行多个语句的触发器。 在BEGIN块中,您还可以使用存储例程(例如条件和循环)中允许的其他语法。 但是,就像存储例程一样,如果使用mysql程序定义执行多个语句的触发器,则必须重新定义mysql语句分隔符,以便可以使用; 触发器定义中的语句分隔符。 以下示例说明了这些要点。 它定义了一个UPDATE触发器,用于检查用于更新每一行的新值,并将值修改到0到100之间。这必须是BEFORE触发器,因为在用于更新之前必须检查行的值:
mysql> delimiter //
mysql>CREATETRIGGERupd_checkBEFORE
UPDATEONaccountFOREACHROW
BEGINIFNEW.amount<0THENSETNEW.amount=0;
ELSEIFNEW.amount>100THENSETNEW.amount=100;
ENDIF;
END;//
mysql>delimiter;
可以更容易地单独定义存储过程,然后使用简单的CALL语句从触发器调用它。 如果要从多个触发器中执行相同的代码,这也是有利的。
触发器在执行时其中执行的语句的内容有一些限制:
MySQL在触发器执行期间处理错误,如下所示
23.3.2 触发器元数据
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3148089/ ,如需转载,请注明出处,否则将追究法律责任。