## A.4 MySQL 8.0 常见问题解答:存储过程和函数 [](<>)A.4.1。[MySQL 8.0 是否支持存储过程和函数?](faqs-stored-procs.html#faq-mysql-have-procedures-functions)A.4.2。[在哪里可以找到 MySQL 存储过程和存储函数的文档?](faqs-stored-procs.html#faq-mysql-where-procedures-functions-docs)A.4.3。[有 MySQL 存储过程的论坛吗?](faqs-stored-procs.html#faq-mysql-where-procedures-forum)A.4.4。[在哪里可以找到存储过程的 ANSI SQL 2003 规范?](faqs-stored-procs.html#faq-mysql-where-ansi-2003-spec)A.4.5。[您如何管理存储的例程?](faqs-stored-procs.html#faq-mysql-how-manage-routines)A.4.6。[有没有办法查看给定数据库中的所有存储过程和存储函数?](faqs-stored-procs.html#faq-mysql-how-view-procedures-functions)A.4.7. [存储过程存储在哪里?](faqs-stored-procs.html#faq-mysql-where-procedures-stored)A.4.8. [是否可以将存储过程或存储函数分组到包中?](faqs-stored-procs.html#faq-mysql-how-group-procedures-functions)A.4.9。[一个存储过程可以调用另一个存储过程吗?](faqs-stored-procs.html#faq-mysql-can-procedure-call-procedure)A.4.10。[存储过程可以调用触发器吗?](faqs-stored-procs.html#faq-mysql-can-procedure-call-trigger)A.4.11。[存储过程可以访问表吗?](faqs-stored-procs.html#faq-mysql-can-procedure-access-table)A.4.12。[存储过程是否有引发应用程序错误的声明?](faqs-stored-procs.html#faq-mysql-can-procedure-raise-error)A.4.13。[存储过程是否提供异常处理?](faqs-stored-procs.html#faq-mysql-have-exceptions)A.4.14。[MySQL 8.0 存储例程可以返回结果集吗?](faqs-stored-procs.html#faq-mysql-can-routine-results)A.4.15。[存储过程是否支持 WITH RECOMPILE?](faqs-stored-procs.html#faq-mysql-have-with-recompile)A.4.16。[是否有相当于使用 mod 的 MySQL_plsql 作为 Apache 上的网关直接与数据库中的存储过程对话?](faqs-stored-procs.html#faq-mysql-have-mod-plsql)A.4.17. [我可以将数组作为输入传递给存储过程吗?](faqs-stored-procs.html#faq-mysql-can-procedure-array)A.4.18. [我可以将游标作为 IN 参数传递给存储过程吗?](faqs-stored-procs.html#faq-mysql-can-pass-cursor-in)A.4.19。[我可以从存储过程中将游标作为 OUT 参数返回吗?](faqs-stored-procs.html#faq-mysql-can-return-cursor-out)A.4.20。[我可以在存储的例程中打印出变量的值以进行调试吗?](faqs-stored-procs.html#faq-mysql-can-print-var-in-procedure)A.4.21。[我可以在存储过程中提交或回滚事务吗?](faqs-stored-procs.html#faq-mysql-can-rollback-transaction-procedure)A.4.22。[MySQL 8.0 存储过程和函数是否适用于复制?](faqs-stored-procs.html#faq-mysql-can-procedures-replicatation)A.4.23。[复制源服务器上创建的存储过程和函数是否复制到副本?](faqs-stored-procs.html#faq-mysql-are-procedures-replicated)A.4.24。[如何复制存储过程和函数内部发生的操作?](faqs-stored-procs.html#faq-mysql-how-procedures-replicated)A.4.25。[将存储过程和函数与复制一起使用是否有特殊的安全要求?](faqs-stored-procs.html#faq-mysql-security-procedures-replication)A.4.26。[复制存储过程和函数操作存在哪些限制?](faqs-stored-procs.html#faq-mysql-limitations-procedures-replication)A.4.27。[上述限制是否会影响 MySQL 进行时间点恢复的能力?](faqs-stored-procs.html#faq-mysql-limitations-pit-recovery)A.4.28。[正在采取什么措施来纠正上述限制?](faqs-stored-procs.html#faq-mysql-when-limitations-resolved) | [](<>)[](<>)

**A.4.1。** | MySQL 8.0 是否支持存储过程和函数? | | :------------------------------- | :--------------------- | | | 是的。MySQL 8.0 支持两种类型的存储例程,存储过程和存储函数。 | | [](<>)[](<>)

**A.4.2。** | 在哪里可以找到 MySQL 存储过程和存储函数的文档? | | | 看[第 25.2 节,“使用存储的例程”](stored-routines.html). | | [](<>)[](<>)

**A.4.3。** | 有 MySQL 存储过程的论坛吗? | | | 是的。看. | | [](<>)[](<>)

**A.4.4。** | 在哪里可以找到存储过程的 ANSI SQL 2003 规范? | | | 不幸的是,官方规范不是免费提供的(ANSI 使它们可供购买)。不过也有书籍,比如*SQL-99 完整,真的*Peter Gulutzan 和 Trudy Pelzer 提供了该标准的全面概述,包括存储过程的覆盖范围。 | | [](<>)[](<>)

**A.4.5。** | 您如何管理存储的例程? | | | 为存储的例程使用清晰的命名方案始终是一种好习惯。您可以管理存储过程`创建 [功能|程序]`,`更改 [功能|程序]`,`删除 [功能|程序]`, 和`显示创建 [功能|程序]`.您可以使用以下方法获取有关现有存储过程的信息[`例行公事`](information-schema-routines-table.html)表中的`INFORMATION_SCHEMA`数据库(见[第 26.3.30 节,“信息\_SCHEMA 例程表”](information-schema-routines-table.html))。 | | [](<>)[](<>)

**A.4.6。** | 有没有办法查看给定数据库中的所有存储过程和存储函数? | | | 是的。对于名为*`数据库名称`*, 在[`INFORMATION_SCHEMA.ROUTINES`](information-schema-routines-table.html)桌子:

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

有关详细信息,请参阅[第 26.3.30 节,“信息\_SCHEMA 例程表”](information-schema-routines-table.html).

可以使用查看存储例程的主体[`显示创建函数`](show-create-function.html)(对于存储的功能)或[`显示创建过程`](show-create-procedure.html)(对于存储过程)。看[第 13.7.7.9 节,“SHOW CREATE PROCEDURE 语句”](show-create-procedure.html), 了解更多信息。 | | [](<>)[](<>)

**A.4.7.** | 存储过程存储在哪里? | | | 存储过程存储在`mysql.routines`和`mysql.参数`表,它们是数据字典的一部分。您不能直接访问这些表。相反,查询`INFORMATION_SCHEMA` [`例行公事`](information-schema-routines-table.html)和[`参数`](information-schema-parameters-table.html)表。看[第 26.3.30 节,“信息\_SCHEMA 例程表”](information-schema-routines-table.html), 和[第 26.3.20 节,“信息\_模式参数表”](information-schema-parameters-table.html).

你也可以使用[`显示创建函数`](show-create-function.html)获取有关存储函数的信息,以及[`显示创建过程`](show-create-procedure.html)获取有关存储过程的信息。看见[第13.7.7.9节,“显示创建程序语句”](show-create-procedure.html). | | [](<>)[](<>)

**A.4.8。** | 是否可以将存储过程或存储函数分组到包中? | | | 不支持。MySQL 8.0不支持这一点。 | | [](<>)[](<>)

**A.4.9。** | 一个存储过程可以调用另一个存储过程吗? | | | 对 | | [](<>)[](<>)

**A.4.10。** | 存储过程可以调用触发器吗? | | | 存储过程可以执行SQL语句,例如[`使现代化`](update.html),这会导致触发器激活。 | | [](<>)[](<>)

**A.4.11。** | 存储过程可以访问表吗? | | | 对存储过程可以根据需要访问一个或多个表。 | | [](<>)[](<>)

**A.4.12。** | 存储过程是否有引发应用程序错误的语句? | | | 对MySQL 8.0实现了SQL标准`信号`和`辞职的`声明。看见[第13.6.7节“条件处理”](condition-handling.html). | | [](<>)[](<>)

**A.4.13。** | 存储过程是否提供异常处理? | | | MySQL实现[`处理者`](handler.html)根据SQL标准定义。看见[第13.6.7.2节,“声明……处理程序声明”](declare-handler.html),以获取详细信息。 | | [](<>)[](<>)

**A.4.14。** | MySQL 8.0存储例程能否返回结果集? | | | *存储过程*可以,但存储函数不能。如果你做一个普通的[`选择`](select.html)在存储过程中,结果集直接返回给客户机。您需要使用MySQL 4.1(或更高版本)的客户机/服务器协议才能工作。这意味着,例如,在PHP中,您需要使用`mysqli`扩展而不是旧的`mysql`扩大 | | [](<>)[](<>)

**A.4.15。** | 是`重新编译`是否支持存储过程? | | | MySQL 8.0中没有。 | | [](<>)[](<>)

**A.4.16。** | 是否有一个MySQL等价于使用`mod_plsql`作为Apache上的网关直接与数据库中的存储过程对话? | | | MySQL 8.0中没有类似的版本。 | | [](<>)[](<>)

**A.4.17。** | 我可以将数组作为输入传递给存储过程吗? | | | MySQL 8.0中没有。 | | [](<>)[](<>)

**A.4.18。** | 我可以将光标作为`在里面`存储过程的参数? | | | 在MySQL 8.0中,游标仅在存储过程中可用。 | | [](<>)[](<>)

**A.4.19。** | 我可以返回一个游标作为`出来`存储过程中的参数? | | | 在MySQL 8.0中,游标仅在存储过程中可用。但是,如果不在屏幕上打开光标[`选择`](select.html),结果将直接发送到客户端。你也可以`选择进入`变量。看见[第13.2.10节“选择声明”](select.html). | | [](<>)[](<>)

**A.4.20。** | 我可以打印出存储例程中的变量值以进行调试吗? | | | 是的,你可以在短时间内完成*存储过程*,但不在存储函数中。如果你做一个普通的[`选择`](select.html)在存储过程中,结果集直接返回给客户机。必须使用MySQL 4.1(或更高版本)客户机/服务器协议才能工作。这意味着,例如,在PHP中,您需要使用`mysqli`扩展而不是旧的`mysql`扩大 | | [](<>)[](<>)

**A.4.21。** | 我可以在存储过程中提交或回滚事务吗? | | | 对但是,不能在存储函数中执行事务操作。 | | [](<>)[](<>)

**A.4.22。** | MySQL 8.0存储过程和函数是否与复制配合使用? | | | 是的,在存储过程和函数中执行的标准操作会从复制源服务器复制到副本。中详细描述了一些限制[第25.7节,“存储程序二进制记录”](stored-programs-logging.html). | | [](<>)[](<>)

**A.4.23。** | 在复制源服务器上创建的存储过程和函数是否已复制到副本? | | | 是的,通过复制源服务器上的正常DDL语句执行的存储过程和函数的创建会复制到一个副本中,这样两台服务器上都存在对象。`改变`和`滴`存储过程和函数的语句也会被复制。 | | [](<>)[](<>)

**A.4.24。** | 存储过程和函数中发生的操作是如何复制的? | | | MySQL记录存储过程中发生的每个DML事件,并将这些单独的操作复制到副本中。为执行存储过程而进行的实际调用不会被复制。

更改数据的存储函数记录为函数调用,而不是每个函数内部发生的DML事件。 | | [](<>)[](<>)

**A.4.25。** | 与复制一起使用存储过程和函数是否有特殊的安全要求? | | | 对因为复制副本有权执行从源二进制日志读取的任何语句,所以在复制时使用存储函数存在特殊的安全约束。如果复制或二进制日志记录(用于时间点恢复)处于活动状态,那么MySQL DBA有两个安全选项可供选择:

1.任何希望创建存储函数的用户都必须被授予[`超级的`](privileges-provided.html#priv_super)特权

2.或者,DBA可以设置[`日志\u bin\u信任\u函数\u创建者`](replication-options-binary-log.html#sysvar_log_bin_trust_function_creators)系统变量设置为1,这使任何人都可以使用该标准[`创建例行程序`](privileges-provided.html#priv_create-routine)创建存储函数的权限。 | | [](<>)[](<>)

**A.4.26。** | 复制存储过程和函数操作存在哪些限制? | | | 存储过程中嵌入的不确定(随机)或基于时间的操作可能无法正确复制。就其本质而言,随机产生的结果是不可预测的,也无法准确复制;因此,复制到副本的随机操作不会镜像在源上执行的操作。将存储函数声明为`确定性`或者设置[`日志\u bin\u信任\u函数\u创建者`](replication-options-binary-log.html#sysvar_log_bin_trust_function_creators)将系统变量设置为0可防止调用生成随机值的随机操作。

此外,基于时间的操作无法在副本上复制,因为存储过程中此类操作的计时无法通过用于复制的二进制日志进行复制。它只记录DML事件,不考虑时间限制。

最后,在大型DML操作(例如大容量插入)期间发生错误的非事务表可能会遇到复制问题,因为可能会从DML活动中部分更新源,但由于发生的错误,不会对复制副本进行更新。解决方法是使用`忽视`关键字,以便忽略源上导致错误的更新,并将不会导致错误的更新复制到副本。 | | [](<>)[](<>)

**A.4.27。** | 上述限制是否会影响MySQL进行时间点恢复的能力? | | | 影响复制的限制也会影响时间点恢复。 | | [](<>)[](<>)

**A.4.28。** | 正在采取哪些措施来纠正上述限制? | | | 您可以选择基于语句的复制或基于行的复制。最初的复制实现基于基于语句的二进制日志记录。基于行的二进制日志记录解决了前面提到的限制。

还可以使用混合复制(通过使用[`--binlog格式=混合`](replication-options-binary-log.html#sysvar_binlog_format))。这种混合复制形式“知道”是否可以安全使用语句级复制,或者是否需要行级复制。

有关更多信息,请参阅[第17.2.1节,“复制格式”](replication-formats.html). |