MySQL не поддерживает рекурсивные функции? Зачем? с каких пор?
Я написал хранимую функцию, которая вызывает себя, рекурсивно.
Однако, когда я запускаю его в запросе, я получаю эту бесстыдную ошибку:
Ошибка: 1424 SQLSTATE: HY000 (ER_SP_NO_RECURSION)
Сообщение: рекурсивные сохраненные функции и триггеры недопустимы.
"Не положено"?
Правильно. Почему бы нам просто не отключить циклы WHILE, пока мы на этом?
Можно ли каким-либо образом включить рекурсивные функции?
Я нашел сообщение об ошибке, но есть ли обходные пути?
Я использую MySQL 5.1.41 в Windows XP (XAMPP Server).
3 ответа
Нет проблем, Дженко. Не так эффективно, как функции 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 5.1 поддерживает рекурсивные хранимые процедуры, но не рекурсивные функции. Цитирование документов:
Сохраненные функции не могут быть рекурсивными.
Рекурсия в хранимых процедурах разрешена, но по умолчанию отключена. Чтобы включить рекурсию, установите
max_sp_recursion_depth
системная переменная сервера со значением больше нуля. Рекурсия хранимой процедуры увеличивает потребность в пространстве стека потока. Если вы увеличите значениеmax_sp_recursion_depth
может потребоваться увеличить размер стека потоков за счет увеличения значенияthread_stack
при запуске сервера.
Вероятно, рекурсия в хранимых подпрограммах не рекомендуется, потому что MySQL должен ограничить размер стека своих потоков.
MySQL обычно использует один поток на соединение. 100 или 1000 соединений являются общими.
На 32-битных платформах при работе с 1000 потоков существует значительное давление в адресном пространстве, поэтому стеки должны быть очень маленькими, чтобы избежать исчерпания адресного пространства.
Переполнение стека, конечно, очень плохо - его нельзя безопасно восстановить. Поэтому я думаю, что MySQL делает это для предотвращения переполнения стека, особенно на 32-битных платформах.
Тем не менее, любой, кто использует 32-битную ОС для производственного сервера MySQL в настоящее время, безумен.