Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности

Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
02.07.2018, 17:19
|
|||
|---|---|---|---|
|
|||
Незапускает рекурсивная процедура |
|||
|
#18+
У меня есть три таблички. В одной описание деталей. В другой история закупочных цен детали. И третья список используемых материалов для производства этой детали. Есть вложенность т.е. одна деталь может в ходить в состав другой детали и так далее. Вложенность не большая, максимуим 5 уровней. Мне нужно было посчитать объем материалов необходимых для производства конкретной детали. Т.е. разложить на материалы из чего она состоит. Получается нужна рекурсивная функция. Но тут есть сложности в Mysql с рекурсией. Я создал функцию FGetListDetails в которую я передаю ID детали и сколько их надо. А она запускает процедуру PGetListDetails, потому как рекурсивно функцию нельзя вызывать, только процедуру. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Процедура PGetListDetails проверяет, что если есть закупочная цена, то я записываю эту деталь в таблицу ListDetailsForReserve, затем получаю список материалов нужных для этой детали и используя курсор запускаю процедуру PGetListDetails для каждого материала. Получается рекурсия. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. В итоге на выходе я должен получить в таблице ListDetailsForReserve список необходимых материалов. Вот так я запускал этот весь маханизм для теста Код: plsql 1. 2. 3. 4. 5. 6. 7. По факту сначала разобрался с проблемай нехватки стека Thread stack overrun и thread_stack=4M, Но после этого появилась эта ошибка Код: sql 1. 2. Как я только не менял SET SESSION max_sp_recursion_depth=500; Но сделать этот параметр выше 255 невозможно. А по сути у меня нет такой вложенности. У меня максиму вложенность на 5 уровней. Не знаю зачем там такая нужна. Может где ошибка есть. Я думал, что может цикл не завершается. Но вроде нет. Может если курсор сразу пустой, то может он не звершается. Вызывал еще процедуру напрямую так Код: sql 1. В этот раз в таблицу записывается, только пару записей и снова таже ошибка Код: sql 1. 2. Проверял это на Хостинге, и на двух своих серверах. Везде одна и таже ошибка. В чем может быть дело ? Версии серверов 5.7 и 5.5.29 Прилагаю дамп трех этих таблиц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.07.2018, 17:47
|
|||
|---|---|---|---|
|
|||
Незапускает рекурсивная процедура |
|||
|
#18+
Не ужели ни укого не было таких проблем ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
04.07.2018, 07:26
|
|||
|---|---|---|---|
Незапускает рекурсивная процедура |
|||
|
#18+
JonnikПолучается нужна рекурсивная функция.Поскольку максимальная глубина вложенности известна и ограничена - нет, не обязательно. JonnikА по сути у меня нет такой вложенности.Логики у тебя нет. А вложенность такая - есть. Посмотри на свой код. Вот на этот фрагмент: Jonnik Код: plsql 1. 2. 3. 4. 5. 6. Ты открываешь курсор. Потом входишь в цикл (на старте Done = 0, не спорь, входишь в любом случае). Потом фетчишь курсор. Если вдруг он пуст - то присваиваешь Done = 1. А дальше безусловно, без всяких проверок, вызываешь следующий уровень рекурсии. И так продолжается, пока он не станет равен 255 - и, как итог, ошибка. Запомни накрепко - если используешь DO-LOOP, первый фетч всегда делается ДО первой провеки флага. В твоём случае - до входа в цикл. И следующие фетчи также делаются непосредственно перед проверкой - то есть последним оператором в цикле. Но ещё лучше - используй REPEAT. И тупой IF Done = 1 THEN LEAVE REPEAT сразу после фетча. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=47&tablet=1&tid=1829749]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
32ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
| others: | 244ms |
| total: | 380ms |

| 0 / 0 |
