8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 81%

A.5 MySQL 8.4 常见问题:触发器A.5 MySQL 8.4 FAQ: Triggers

A.5.1. 我在哪里可以找到 MySQL 8.4 触发器的文档? A.5.1. Where can I find the documentation for MySQL 8.4 triggers?
A.5.2. 是否有关于 MySQL 触发器的讨论论坛? A.5.2. Is there a discussion forum for MySQL Triggers?
A.5.3. MySQL 是否有语句级或行级触发器? A.5.3. Does MySQL have statement-level or row-level triggers?
A.5.4. 是否有默认触发器? A.5.4. Are there any default triggers?
A.5.5. MySQL 中的触发器如何管理? A.5.5. How are triggers managed in MySQL?
A.5.6. 有没有方法查看指定数据库中的所有触发器? A.5.6. Is there a way to view all triggers in a given database?
A.5.7. 触发器存储在哪里? A.5.7. Where are triggers stored?
A.5.8. 触发器可以调用存储过程吗? A.5.8. Can a trigger call a stored procedure?
A.5.9. 触发器可以访问表吗? A.5.9. Can triggers access tables?
A.5.10. 一个表可以有多个具有相同触发事件和动作时间的触发器吗? A.5.10. Can a table have multiple triggers with the same trigger event and action time?
A.5.11. 触发器可以更新远程服务器上的表吗? A.5.11. Is it possible for a trigger to update tables on a remote server?
A.5.12. 触发器在复制中有效吗? A.5.12. Do triggers work with replication?
A.5.13. 通过触发器在源上执行的操作如何复制到副本? A.5.13. How are actions carried out through triggers on a source replicated to a replica?

A.5.1.

我在哪里可以找到 MySQL 8.4 触发器的文档?Where can I find the documentation for MySQL 8.4 triggers?

请参见 第 27.3 节,“使用触发器”。See Section 27.3, “Using Triggers”.

A.5.2.

MySQL 触发器有讨论论坛吗?Is there a discussion forum for MySQL Triggers?

有。可以在 https://forums.mysql.com/list.php?99 访问。Yes. It is available at https://forums.mysql.com/list.php?99.

A.5.3.

MySQL 是否有语句级或行级触发器?Does MySQL have statement-level or row-level triggers?

所有触发器都是 FOR EACH ROW;也就是说,触发器会在每条插入、更新或删除的行上被激活。MySQL 不支持使用 FOR EACH STATEMENT 的触发器。All triggers are FOR EACH ROW; that is, the trigger is activated for each row that is inserted, updated, or deleted. MySQL does not support triggers using FOR EACH STATEMENT.

A.5.4.

有默认触发器吗?Are there any default triggers?

没有明确说明。MySQL 确实对一些 TIMESTAMP 列以及使用 AUTO_INCREMENT 定义的列具有特定的特殊行为。Not explicitly. MySQL does have specific special behavior for some TIMESTAMP columns, as well as for columns which are defined using AUTO_INCREMENT.

A.5.5.

MySQL 中如何管理触发器?How are triggers managed in MySQL?

触发器可以使用 CREATE TRIGGER 语句创建,并使用 DROP TRIGGER 删除。有关这些语句的更多信息,请参见 15.1.22 节,“CREATE TRIGGER 语句” 和 15.1.34 节,“DROP TRIGGER 语句”。Triggers can be created using the CREATE TRIGGER statement, and dropped using DROP TRIGGER. See Section 15.1.22, “CREATE TRIGGER Statement”, and Section 15.1.34, “DROP TRIGGER Statement”, for more about these statements.

有关触发器的信息可以通过查询 INFORMATION_SCHEMA.TRIGGERS 表来获取。参见 第 28.3.44 节,“INFORMATION_SCHEMA TRIGGERS 表”。Information about triggers can be obtained by querying the INFORMATION_SCHEMA.TRIGGERS table. See Section 28.3.44, “The INFORMATION_SCHEMA TRIGGERS Table”.

A.5.6.

有没有办法查看指定数据库中的所有触发器?Is there a way to view all triggers in a given database?

有。您可以使用对 INFORMATION_SCHEMA.TRIGGERS 表的查询来获取数据库 dbname 上定义的所有触发器列表,如下所示:Yes. You can obtain a listing of all triggers defined on database dbname using a query on the INFORMATION_SCHEMA.TRIGGERS table such as the one shown here:

SELECT TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_STATEMENT
    FROM INFORMATION_SCHEMA.TRIGGERS
    WHERE TRIGGER_SCHEMA='dbname';

有关此表的更多信息,请参阅 第 28.3.44 节,“INFORMATION_SCHEMA TRIGGERS 表”。For more information about this table, see Section 28.3.44, “The INFORMATION_SCHEMA TRIGGERS Table”.

您也可以使用 SHOW TRIGGERS 语句,该语句特定于 MySQL。请参阅 第 15.7.7.40 节,“SHOW TRIGGERS 语句”。You can also use the SHOW TRIGGERS statement, which is specific to MySQL. See Section 15.7.7.40, “SHOW TRIGGERS Statement”.

A.5.7.

触发器存储在哪里?Where are triggers stored?

触发器存储在 mysql.triggers 系统表中,它是数据字典的一部分。Triggers are stored in the mysql.triggers system table, which is part of the data dictionary.

A.5.8.

触发器可以调用存储过程吗?Can a trigger call a stored procedure?

可以。Yes.

A.5.9.

触发器可以访问表吗?Can triggers access tables?

触发器可以访问其自身表中的旧数据和新数据。触发器也可以影响其他表,但不允许修改已经被调用该函数或触发器的语句用于读取或写入的表。A trigger can access both old and new data in its own table. A trigger can also affect other tables, but it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.

A.5.10.

一个表可以有多个具有相同触发事件和动作时间的触发器吗?Can a table have multiple triggers with the same trigger event and action time?

在 MySQL 8.4 中,可以为给定表定义多个具有相同触发事件和动作时间的触发器。例如,你可以为一个表设置两个 BEFORE UPDATE 触发器。默认情况下,具有相同触发事件和动作时间的触发器按创建顺序激活。要影响触发器的顺序,可以在 FOR EACH ROW 后指定一个子句,指明 FOLLOWS 或 PRECEDES 以及一个具有相同触发事件和动作时间的现有触发器名称。使用 FOLLOWS 时,新触发器在现有触发器之后激活。使用 PRECEDES 时,新触发器在现有触发器之前激活。In MySQL 8.4, it is possible to define multiple triggers for a given table that have the same trigger event and action time. For example, you can have two BEFORE UPDATE triggers for a table. By default, triggers that have the same trigger event and action time activate in the order they were created. To affect trigger order, specify a clause after FOR EACH ROW that indicates FOLLOWS or PRECEDES and the name of an existing trigger that also has the same trigger event and action time. With FOLLOWS, the new trigger activates after the existing trigger. With PRECEDES, the new trigger activates before the existing trigger.

A.5.11.

触发器能否更新远程服务器上的表?Is it possible for a trigger to update tables on a remote server?

是的。可以使用 FEDERATED 存储引擎更新远程服务器上的表。(参见 第 18.8 节,“FEDERATED 存储引擎”).Yes. A table on a remote server could be updated using the FEDERATED storage engine. (See Section 18.8, “The FEDERATED Storage Engine”).

A.5.12.

触发器在复制中能工作吗?Do triggers work with replication?

能。然而,它们的工作方式取决于你使用的是 MySQL 的 “经典” 基于语句的复制还是基于行的复制格式。Yes. However, the way in which they work depends whether you are using MySQL's “classic” statement-based or row-based replication format.

在使用基于语句的复制时,副本上的触发器由在源服务器上执行并复制到副本上的语句触发。When using statement-based replication, triggers on the replica are executed by statements that are executed on the source (and replicated to the replica).

在使用基于行的复制时,由于在源上执行的语句随后被复制到副本,所以触发器不会在副本上执行。相反,在使用基于行的复制时,在源上执行触发器所引起的更改会应用到副本上。When using row-based replication, triggers are not executed on the replica due to statements that were run on the source and then replicated to the replica. Instead, when using row-based replication, the changes caused by executing the trigger on the source are applied on the replica.

有关更多信息,请参见 第 19.5.1.36 节,“复制和触发器”。For more information, see Section 19.5.1.36, “Replication and Triggers”.

A.5.13.

通过源上的触发器执行的操作如何复制到副本?How are actions carried out through triggers on a source replicated to a replica?

同样,这取决于您是使用基于语句的复制还是基于行的复制。Again, this depends on whether you are using statement-based or row-based replication.

基于语句的复制。 首先,源端存在的触发器必须在副本服务器上重新创建。完成后,复制流程就像处理任何其他参与复制的标准 DML 语句一样。例如,考虑一个表 EMP,它在复制源服务器上有一个 AFTER 插入触发器。同样的 EMP 表和 AFTER 插入触发器也存在于副本服务器上。复制流程如下:Statement-based replication.  First, the triggers that exist on a source must be re-created on the replica server. Once this is done, the replication flow works as any other standard DML statement that participates in replication. For example, consider a table EMP that has an AFTER insert trigger, which exists on a replication source server. The same EMP table and AFTER insert trigger exist on the replica server as well. The replication flow would be:

  1. 对 EMP 执行一个 INSERT 语句。An INSERT statement is made to EMP.

  2. EMP 表上的 AFTER 触发器被激活。The AFTER trigger on EMP activates.

  3. INSERT 语句会被写入二进制日志。The INSERT statement is written to the binary log.

  4. 副本会获取 INSERT 到 EMP 的语句并执行它。The replica picks up the INSERT statement to EMP and executes it.

  5. 位于副本上的 EMP 上的 AFTER 触发器将被激活。The AFTER trigger on EMP that exists on the replica activates.

基于行的复制。 当你使用基于行的复制时,在源端执行触发器所引起的更改会应用到副本上。然而,在基于行的复制下,触发器本身实际上并不会在副本上执行。这是因为,如果源端和副本都应用了源端的更改,并且触发这些更改的触发器也在副本上执行,则这些更改实际上会在副本上应用两次,从而导致源端和副本的数据不一致。Row-based replication.  When you use row-based replication, the changes caused by executing the trigger on the source are applied on the replica. However, the triggers themselves are not actually executed on the replica under row-based replication. This is because, if both the source and the replica applied the changes from the source and, in addition, the trigger causing these changes were applied on the replica, the changes would in effect be applied twice on the replica, leading to different data on the source and the replica.

在大多数情况下,行级复制和语句级复制的结果是相同的。然而,如果源端和副本上使用了不同的触发器,就无法使用行级复制。(这是因为行级格式会将源端触发器执行所产生的更改复制到副本,而不是复制导致触发器执行的语句,而且副本上的对应触发器不会被执行。)相反,任何导致此类触发器执行的语句必须使用语句级复制进行复制。In most cases, the outcome is the same for both row-based and statement-based replication. However, if you use different triggers on the source and replica, you cannot use row-based replication. (This is because the row-based format replicates the changes made by triggers executing on the source to the replicas, rather than the statements that caused the triggers to execute, and the corresponding triggers on the replica are not executed.) Instead, any statements causing such triggers to be executed must be replicated using statement-based replication.

有关更多信息,请参见 第 19.5.1.36 节,“复制和触发器”。For more information, see Section 19.5.1.36, “Replication and Triggers”.