Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  MySQL 8.3 Frequently Asked Questions  /  MySQL 8.3 FAQ: Stored Procedures and Functions

A.4 MySQL 8.3 FAQ:存储过程和函数

A.4.1. MySQL 8.3是否支持存储过程和函数?
A.4.2. 在哪里可以找到MySQL存储过程和存储函数的文档?
A.4.3. 是否有一个讨论论坛用于MySQL存储过程?
A.4.4. 在哪里可以找到ANSI SQL 2003规范的存储过程?
A.4.5. 如何管理存储例程?
A.4.6. 是否有办法查看给定数据库中的所有存储过程和存储函数?
A.4.7. 存储过程存储在哪里?
A.4.8. 是否可以将存储过程或存储函数分组到包中?
A.4.9. 一个存储过程可以调用另一个存储过程吗?
A.4.10. 一个存储过程可以调用触发器吗?
A.4.11. 一个存储过程可以访问表吗?
A.4.12. 存储过程是否有语句来引发应用程序错误?
A.4.13. 存储过程提供异常处理吗?
A.4.14. MySQL 8.3存储例程可以返回结果集吗?
A.4.15. 是否支持WITH RECOMPILE用于存储过程?
A.4.16. 是否有一个MySQL等效于使用mod_plsql作为Apache网关来直接与数据库中的存储过程通信?
A.4.17. 我可以将数组作为输入传递给存储过程吗?
A.4.18. 我可以将游标作为IN参数传递给存储过程吗?
A.4.19. 我可以将游标作为OUT参数从存储过程返回吗?
A.4.20. 我可以在存储例程中打印变量的值以进行调试吗?
A.4.21. 我可以在存储过程中提交或回滚事务吗?
A.4.22. MySQL 8.3存储过程和函数是否与复制一起工作?
A.4.23. 在复制源服务器上创建的存储过程和函数是否被复制到副本?
A.4.24. 存储过程和函数中的操作如何被复制?
A.4.25. 使用存储过程和函数与复制一起工作是否需要特殊的安全要求?
A.4.26. 存储过程和函数的复制存在哪些限制?
A.4.27. 这些限制是否影响了MySQL的点时间恢复能力?
A.4.28. 上述限制何时被解决?
(No translation needed, as this is a HTML structure definition and doesn't contain any translatable text.) becomes: becomes: Here is the translated HTML fragment: 翻译后: 翻译为:

A.4.1.

MySQL 8.3 是否支持存储过程和函数?

是的。MySQL 8.3 支持两种类型的存储例程,存储过程和存储函数。

A.4.2.

哪里可以找到 MySQL 存储过程和存储函数的文档?

请参阅 第 27.2 节,“使用存储例程”

A.4.3.

是否有一个讨论论坛用于 MySQL 存储过程?

是的。请参阅 https://forums.mysql.com/list.php?98

A.4.4.

哪里可以找到 ANSI SQL 2003 规范的存储过程?

不幸的是,官方规范不可免费获取(ANSI 将其出售)。然而,有些书籍,如 Peter Gulutzan 和 Trudy Pelzer 的《SQL-99 Complete, Really》,提供了对标准的综合概述,包括存储过程的 coverage。

A.4.5.

如何管理存储例程?

总是使用明确的命名方案来管理存储例程。您可以使用 CREATE [FUNCTION|PROCEDURE]ALTER [FUNCTION|PROCEDURE]DROP [FUNCTION|PROCEDURE]SHOW CREATE [FUNCTION|PROCEDURE] 来管理存储过程。您可以使用 ROUTINES 表在 INFORMATION_SCHEMA 数据库中获取关于现有存储过程的信息(请参阅 第 28.3.30 节,“The INFORMATION_SCHEMA ROUTINES Table”)。

A.4.6.

是否可以查看给定数据库中的所有存储过程和存储函数?

是的。对于名为 dbname 的数据库,使用以下查询在 INFORMATION_SCHEMA.ROUTINES 表中:

SELECT ROUTINE_TYPE, ROUTINE_NAME
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_SCHEMA='dbname';

更多信息,请参阅 第 28.3.30 节,“The INFORMATION_SCHEMA ROUTINES Table”

存储例程的主体可以使用 SHOW CREATE FUNCTION(对于存储函数)或 SHOW CREATE PROCEDURE(对于存储过程)来查看。请参阅 第 15.7.7.10 节,“SHOW CREATE PROCEDURE 语句”,以获取更多信息。

A.4.7.

存储过程存储在哪里?

A.4.1.

MySQL 8.3 是否支持存储过程和函数?

是的。MySQL 8.3 支持两种类型的存储例程,存储过程和存储函数。

A.4.2.

哪里可以找到 MySQL 存储过程和存储函数的文档?

请参阅 第 27.2 节,“使用存储例程”

A.4.3.

是否有一个讨论论坛用于 MySQL 存储过程?

是的。请参阅 https://forums.mysql.com/list.php?98

A.4.4.

哪里可以找到 ANSI SQL 2003 规范的存储过程?

不幸的是,官方规范不可免费获取(ANSI 将其出售)。然而,有些书籍,如 Peter Gulutzan 和 Trudy Pelzer 的《SQL-99 Complete, Really》,提供了对标准的综合概述,包括存储过程的 coverage。

A.4.5.

如何管理存储例程?

总是使用明确的命名方案来管理存储例程。您可以使用 CREATE [FUNCTION|PROCEDURE]ALTER [FUNCTION|PROCEDURE]DROP [FUNCTION|PROCEDURE]SHOW CREATE [FUNCTION|PROCEDURE] 来管理存储过程。您可以使用 ROUTINES 表在 INFORMATION_SCHEMA 数据库中获取关于现有存储过程的信息(请参阅 第 28.3.30 节,“The INFORMATION_SCHEMA ROUTINES Table”)。

A.4.6.

是否可以查看给定数据库中的所有存储过程和存储函数?

是的。对于名为 dbname 的数据库,使用以下查询在 INFORMATION_SCHEMA.ROUTINES 表中:

SELECT ROUTINE_TYPE, ROUTINE_NAME
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_SCHEMA='dbname';

更多信息,请参阅 第 28.3.30 节,“The INFORMATION_SCHEMA ROUTINES Table”

存储例程的主体可以使用 SHOW CREATE FUNCTION(对于存储函数)或 SHOW CREATE PROCEDURE(对于存储过程)来查看。请参阅 第 15.7.7.10 节,“SHOW CREATE PROCEDURE 语句”,以获取更多信息。

A.4.7.

存储过程存储在哪里?

A.4.1.

MySQL 8.3 是否支持存储过程和函数?

是的。MySQL 8.3 支持两种类型的存储例程,存储过程和存储函数。

A.4.2.

哪里可以找到 MySQL 存储过程和存储函数的文档?

请参阅 第 27.2 节,“使用存储例程”

A.4.3.

是否有一个讨论论坛用于 MySQL 存储过程?

是的。请参阅 https://forums.mysql.com/list.php?98

A.4.4.

哪里可以找到 ANSI SQL 2003 规范的存储过程?

不幸的是,官方规范不可免费获取(ANSI 将其出售)。然而,有些书籍,如 Peter Gulutzan 和 Trudy Pelzer 的《SQL-99 Complete, Really》,提供了对标准的综合概述,包括存储过程的 coverage。

A.4.5.

如何管理存储例程?

总是使用明确的命名方案来管理存储例程。您可以使用 CREATE [FUNCTION|PROCEDURE]ALTER [FUNCTION|PROCEDURE]DROP [FUNCTION|PROCEDURE]SHOW CREATE [FUNCTION|PROCEDURE] 来管理存储过程。您可以使用 ROUTINES 表在 INFORMATION_SCHEMA 数据库中获取关于现有存储过程的信息(请参阅 第 28.3.30 节,“The INFORMATION_SCHEMA ROUTINES Table”)。

A.4.6.

是否可以查看给定数据库中的所有存储过程和存储函数?

是的。对于名为 dbname 的数据库,使用以下查询在 INFORMATION_SCHEMA.ROUTINES 表中:

SELECT ROUTINE_TYPE, ROUTINE_NAME
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_SCHEMA='dbname';

更多信息,请参阅 第 28.3.30 节,“The INFORMATION_SCHEMA ROUTINES Table”

存储例程的主体可以使用 SHOW CREATE FUNCTION(对于存储函数)或 SHOW CREATE PROCEDURE(对于存储过程)来查看。请参阅 第 15.7.7.10 节,“SHOW CREATE PROCEDURE 语句”,以获取更多信息。

A.4.7.

存储过程存储在哪里?

存储过程存储在 mysql.routinesmysql.parameters 表中,这些表是数据字典的一部分。您不能直接访问这些表。相反,查询 INFORMATION_SCHEMA ROUTINESPARAMETERS 表。见 第 28.3.30 节,“INFORMATION_SCHEMA ROUTINES 表”,和 第 28.3.20 节,“INFORMATION_SCHEMA PARAMETERS 表”

您也可以使用 SHOW CREATE FUNCTION 获取存储函数的信息,并使用 SHOW CREATE PROCEDURE 获取存储过程的信息。见 第 15.7.7.10 节,“SHOW CREATE PROCEDURE 语句”

A.4.8.

是否可以将存储过程或存储函数分组到包中?

不,MySQL 8.3 不支持这种功能。

A.4.9.

存储过程可以调用另一个存储过程吗?

是的。

A.4.10.

存储过程可以调用触发器吗?

存储过程可以执行 SQL 语句,例如 UPDATE,从而激活触发器。

A.4.11.

存储过程可以访问表吗?

是的。存储过程可以根据需要访问一个或多个表。

A.4.12.

存储过程是否有语句来引发应用程序错误?

是的。MySQL 8.3 实现了 SQL 标准 SIGNALRESIGNAL 语句。见 第 15.6.7 节,“Condition Handling”

A.4.13.

存储过程是否提供异常处理?

MySQL 实现了 HANDLER 定义,按照 SQL 标准。见 第 15.6.7.2 节,“DECLARE ... HANDLER 语句”,以获取详细信息。

A.4.14.

MySQL 8.3 存储例程是否可以返回结果集?

存储过程 可以,但存储函数不能。如果您在存储过程中执行普通的 SELECT 语句,结果集将直接返回给客户端。您需要使用 MySQL 4.1(或更高版本)的客户端/服务器协议来实现此功能。这意味着,例如,在 PHP 中,您需要使用 mysqli 扩展,而不是旧的 mysql 扩展。

A.4.15.

是否支持 WITH RECOMPILE 语句用于存储过程?

在 MySQL 8.3 中不可用。

A.4.16.

是否有 MySQL 等同于使用 mod_plsql 作为 Apache 网关直接与数据库中的存储过程通信的等效项?

在 MySQL 8.3 中没有等效项。

A.4.17.

是否可以将数组作为输入传递给存储过程?

在 MySQL 8.3 中不可用。

A.4.18.

是否可以将游标作为 IN 参数传递给存储过程?

在 MySQL 8.3 中,游标仅在存储过程内部可用。

A.4.19.

是否可以将游标作为 OUT 参数从存储过程返回?

在 MySQL 8.3 中,游标仅在存储过程内部可用。然而,如果您不打开游标来执行 SELECT,结果将直接发送到客户端。您也可以使用 SELECT INTO 变量。请参阅 第 15.2.13 节,“SELECT 语句”

A.4.20.

是否可以在存储过程中打印变量的值以进行调试?

是的,您可以在 存储过程 中这样做,但不能在存储函数中这样做。如果您在存储过程中执行普通的 SELECT,结果集将直接返回到客户端。您需要使用 MySQL 4.1(或更高版本)的客户端/服务器协议来使其生效。例如,在 PHP 中,您需要使用 mysqli 扩展,而不是旧的 mysql 扩展。

A.4.21.

是否可以在存储过程中提交或回滚事务?

是的。但是,您不能在存储函数中执行事务操作。

A.4.22.

MySQL 8.3 存储过程和函数是否与复制兼容?

是的,标准操作在存储过程和函数中执行的操作将从复制源服务器复制到副本。有一些限制,详见 第 27.7 节,“存储程序二进制日志记录”

A.4.23.

存储过程和函数是否在复制源服务器上创建并复制到副本?

是的,在复制源服务器上通过普通 DDL 语句创建的存储过程和函数将被复制到副本,以便在两个服务器上都存在这些对象。ALTERDROP 语句对于存储过程和函数也将被复制。

A.4.24.

存储过程和函数中的操作如何被复制?

MySQL 记录了存储过程中的每个 DML 事件,并将这些事件复制到副本。实际执行存储过程的调用不会被复制。

更改数据的存储函数将被记录为函数调用,而不是作为 DML 事件。

A.4.25.

使用存储过程和函数与复制一起时,是否有特殊的安全要求?

是的。因为副本有权执行来自源的二进制日志中的任何语句,因此在使用存储函数与复制时存在特殊的安全约束。如果启用了复制或二进制日志记录(用于点时间恢复),那么 MySQL DBA 有两个安全选项可供选择:

  1. 任何想要创建存储函数的用户都必须被授予 SUPER 权限。

  2. 或者,DBA 可以将 log_bin_trust_function_creators 系统变量设置为 1,这样任何拥有标准 CREATE ROUTINE 权限的人都可以创建存储函数。

A.4.26.

存储过程和函数操作的复制存在哪些限制?

嵌入存储过程中的非确定性(随机)或基于时间的操作不能正确地复制。由于随机产生的结果不可预测,因此无法在副本上精确地重现随机操作。声明存储函数为 DETERMINISTIC 或将 log_bin_trust_function_creators 系统变量设置为 0,可以防止随机操作产生随机值。

此外,基于时间的操作也不能在副本上重现,因为存储过程中的时间约束无法通过二进制日志记录来复制。

最后,对于非事务表,如果大型 DML 操作(如批量插入)出现错误,可能会出现复制问题。在这种情况下,源可能会部分更新,而副本不会更新,因为错误会导致更新失败。解决方法是使用 IGNORE 关键字,使源上的更新忽略错误,并将正确的更新复制到副本上。

A.4.27.

这些限制是否会影响 MySQL 的点时间恢复能力?

这些限制同样会影响点时间恢复。

A.4.28.

这些限制何时会被解决?

您可以选择基于语句的复制或基于行的复制。原始的复制实现基于基于语句的二进制日志记录。基于行的二进制日志记录解决了前面提到的限制。

混合 复制也可用(通过使用 --binlog-format=mixed 启动服务器)。这种混合形式的复制 知道 何时可以安全地使用基于语句的复制,何时需要基于行的复制。

有关更多信息,请参阅 第 19.2.1 节,“复制格式”

这些限制同样会影响点时间恢复。

A.4.28.

这些限制何时会被解决?

您可以选择基于语句的复制或基于行的复制。原始的复制实现基于基于语句的二进制日志记录。基于行的二进制日志记录解决了前面提到的限制。

混合 复制也可用(通过使用 --binlog-format=mixed 启动服务器)。这种混合形式的复制 知道 何时可以安全地使用基于语句的复制,何时需要基于行的复制。

有关更多信息,请参阅 第 19.2.1 节,“复制格式”

这些限制同样会影响点时间恢复。

A.4.28.

这些限制何时会被解决呢?

您可以选择基于语句的复制或基于行的复制。原始的复制实现基于基于语句的二进制日志记录。基于行的二进制日志记录解决了前面提到的限制。

混合 复制也可用(通过使用 --binlog-format=mixed 启动服务器)。这种混合形式的复制 知道 何时可以安全地使用基于语句的复制,何时需要基于行的复制。

有关更多信息,请参阅 第 19.2.1 节,“复制格式”