Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

A.4 MySQL 8.4 常见问题解答:存储过程和函数

A.4.1. MySQL是否支持存储过程和函数?
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存储例程可以返回结果集吗?
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存储过程和函数是否与复制一起工作?
A.4.23. 在复制源服务器上创建的存储过程和函数是否被复制到副本?
A.4.24. 存储过程和函数中的操作如何被复制?
A.4.25. 使用存储过程和函数与复制一起时是否有特殊的安全要求?
A.4.26. 存储过程和函数的复制有什么限制?
A.4.27. 这些限制是否影响了MySQL的点时间恢复能力?
A.4.28. 如何解决这些限制?

A.4.1.

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

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

A.4.2.

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

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

A.4.3.

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

是的。见https://forums.mysql.com/list.php?98

A.4.4.

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

不幸的是,官方规范不可免费获取(ANSI将其提供购买)。然而,有些书籍,如SQL-99 Complete, Really by Peter Gulutzan and Trudy Pelzer,提供了标准的综合概述,包括存储过程的覆盖。

A.4.5.

如何管理存储例程?

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

A.4.6.

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

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

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

更多信息,请见第28.3.30节,“INFORMATION_SCHEMA ROUTINES表”

存储例程的主体可以使用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.

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

不支持。

A.4.9.

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

是的。

A.4.10.

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

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

A.4.11.

存储过程可以访问表吗?

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

A.4.12.

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

是的。 MySQL 实现了 SQL 标准 SIGNALRESIGNAL 语句。见 第 15.6.7 节,“条件处理”

A.4.13.

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

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

A.4.14.

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

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

A.4.15.

是否支持 WITH RECOMPILE for 存储过程?

否。

A.4.16.

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

没有等效项。

A.4.17.

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

否。

A.4.18.

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

游标只能在存储过程中使用。

A.4.19.

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

游标只能在存储过程中使用。然而,如果您不打开游标来执行 SELECT,结果将直接发送给客户端。您也可以 SELECT INTO 变量。见 第 15.2.13 节,“SELECT 语句”

A.4.20.

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

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

A.4.21.

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

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

A.4.22.

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

是的,标准操作在存储过程和函数中执行,这些操作将从复制源服务器复制到副本服务器。有一些限制,这些限制在 第 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 节,“复制格式”