23.8 对存储程序的限制

这些限制适用于第 23 章,存储的对象中描述的功能。

此处指出的某些限制适用于所有存储的例程。也就是存储过程和存储函数。也有一些特定于存储功能的限制,但不是存储过程。

存储功能的限制也适用于触发器。还有一些特定于触发器的限制

对存储过程的限制也适用于 Event Scheduler 事件定义的DO子句。还有一些特定于事件的限制

存储例程中不允许使用 SQL 语句

存储的例程不能包含任意 SQL 语句。以下语句是不允许的:

对存储功能的限制

存储的函数中不允许以下附加语句或操作。它们在存储过程中是允许的,但从存储函数或触发器中调用的存储过程除外。例如,如果在存储过程中使用FLUSH,则不能从存储函数或触发器中调用该存储过程。

触发器限制

对于触发器,以下附加限制适用:

存储例程中的名称冲突

相同的标识符可能用于例程参数,局部变量和 table 列。同样,可以在嵌套块中使用相同的局部变量名称。例如:

CREATE PROCEDURE p (i INT)
BEGIN
  DECLARE i INT DEFAULT 0;
  SELECT i FROM t;
  BEGIN
    DECLARE i INT DEFAULT 1;
    SELECT i FROM t;
  END;
END;

在这种情况下,标识符不明确,并且适用以下优先级规则:

变量优先于 table 列的行为是非标准的。

Replication Considerations

使用存储的例程可能会导致复制问题。 第 23.7 节“存储的程序二进制日志”中将进一步讨论此问题。

--replicate-wild-do-table=db_name.tbl_name选项适用于 table,视图和触发器。它不适用于存储过程和功能或事件。要过滤对后一个对象操作的语句,请使用一个或多个--replicate-*-db选项。

Debugging Considerations

没有存储的例行调试功能。

SQL:2003 标准中不受支持的语法

MySQL 存储的例程语法基于 SQL:2003 标准。当前不支持该标准中的以下各项:

存储的常规并发注意事项

为了防止会话之间的交互问题,当 Client 端发出一条语句时,服务器使用例程快照和可用于执行该语句的触发器。即,服务器计算在语句执行期间可能使用的过程,函数和触发器的列 table,加载它们,然后 continue 执行该语句。语句执行时,看不到其他会话对例程执行的更改。

为了获得最大的并发性,存储函数应将其副作用降到最低。特别是,更新存储功能中的 table 可以减少对该 table 的并发操作。存储的函数在执行之前获取 table 锁,以避免二进制日志由于语句执行 Sequences 和语句出现在日志中的 Sequences 不匹配而导致不一致。使用基于语句的二进制日志记录时,将记录调用函数的语句,而不是记录在函数内执行的语句。因此,更新相同基础 table 的存储函数不会并行执行。相反,存储过程不获取 table 级锁。在存储过程中执行的所有语句都被写入二进制日志,即使对于基于语句的二进制日志也是如此。参见第 23.7 节“存储的程序二进制日志”

事件计划程序限制

以下限制特定于事件计划程序:

存储在 NDB Cluster 中的例程和触发器. 使用NDB存储引擎的 table 均支持存储过程,存储函数和触发器;但是,请务必记住,它们不会在充当群集 SQL 节点的 MySQL 服务器之间自动传播。这是由于以下原因:

与 NDB 群集 table 交互的任何存储例程或触发器都必须通过在要使用该存储例程或触发器的群集中的每个 MySQL Server 上运行相应的CREATE PROCEDURECREATE FUNCTIONCREATE TRIGGER语句来重新创建。同样,必须在所有 Cluster SQL 节点上显式地执行对现有存储例程或触发器的任何更改,并在每个访问群集的 MySQL Server 上使用适当的ALTERDROP语句。

Warning

不要尝试通过将任何mysql数据库 table 转换为使用NDB存储引擎来解决前面提到的第一项中描述的问题。 *不支持更改mysql数据库中的系统 table,并且很可能产生不希望的结果。

首页