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 в настоящее время, безумен.

Другие вопросы по тегам