我写了一个存储的函数,它递归地调用自己。
但是,当我在查询中运行它时,我得到了这个无耻的错误:
错误:1424 SQLSTATE:HY000 (ER_SP_NO_RECURSION)
消息:不允许使用递归存储函数和触发器。
“不允许”?
正确的。我们为什么不直接禁用 WHILE 循环呢?
我可以以任何方式启用递归函数吗?
我发现了一个错误报告,但有什么解决方法吗?
我在 Windows XP(XAMPP 服务器)上运行 MySQL 5.1.41。
我写了一个存储的函数,它递归地调用自己。
但是,当我在查询中运行它时,我得到了这个无耻的错误:
错误:1424 SQLSTATE:HY000 (ER_SP_NO_RECURSION)
消息:不允许使用递归存储函数和触发器。
“不允许”?
正确的。我们为什么不直接禁用 WHILE 循环呢?
我可以以任何方式启用递归函数吗?
我发现了一个错误报告,但有什么解决方法吗?
我在 Windows XP(XAMPP 服务器)上运行 MySQL 5.1.41。
MySQL 5.1 支持递归存储过程,但不支持递归函数。引用文档:
存储函数不能递归。
存储过程中的递归是允许的,但默认情况下是禁用的。要启用递归,请将
max_sp_recursion_depth
服务器系统变量设置为大于零的值。存储过程递归增加了对线程堆栈空间的需求。如果增加 的值max_sp_recursion_depth
,则可能需要通过增加thread_stack
服务器启动时的值来增加线程堆栈大小。
没问题,詹科。效率不如 PostgreSQL 函数,但在 MySQL 过程中也可以:
DELIMITER $$
DROP PROCEDURE IF EXISTS test.factorial_proc$$
CREATE PROCEDURE test.factorial_proc
(
IN n BIGINT,
OUT res BIGINT
)
BEGIN
SET max_sp_recursion_depth=10;
IF n >= 2 THEN
CALL test.factorial_proc (n-1, res);
SELECT n * res INTO res;
ELSE
SELECT n INTO res;
END IF;
END$$
DELIMITER ;
[test]> CALL test.factorial_proc (5, @res);
[test]> CALL test.factorial_proc (5, @res1);
[test]> select @res * @res1;
+--------------+
| @res * @res1 |
+--------------+
| 14400 |
+--------------+
谢尔盖·扎伊采夫。
可能不鼓励存储例程中的递归,因为 MySQL 需要限制其线程的堆栈大小。
MySQL 通常每个连接使用一个线程。100 或 1000 的连接很常见。
在 32 位平台上,当运行 1,000 个线程时,地址空间压力很大,因此需要将堆栈设置得非常小,以避免地址空间耗尽。
堆栈溢出当然是非常糟糕的——它无法安全地恢复。所以我认为 MySQL 这样做是为了防止堆栈溢出,尤其是在 32 位平台上。
也就是说,现在任何使用 32 位操作系统来生产 MySQL 服务器的人都是疯了。