Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте, есть таблица типов товаров:
Неактивен
Или хотя бы подскажите где почитать про рекурсию в хранимых процедурах. Может есть какие-нибудь особенности при объявлении или еще что-нибудь... Перерыл все что можно, ничего полезного.
Неактивен
Делаю вызов вот так:
Неактивен
Насколько я вижу, здесь обсуждение пока еще не ведется
А ошибок / предупреждений не выдает? Я тупо сделал так же, как у Вас — работает.
Единственное «но» — я правильно выставил DELIMITER. Тупой вопрос — у Вас не видно,
чтобы DELIMITER менялись, вы же их меняете, да?
Неактивен
Спасибо, paulus, увидел ТУПЕЙШУЮ ошибку, когда пересматривал этот пост. Здесь я написал, что вызов делаю так:
Отредактированно kaurovis (28.01.2011 11:16:05)
Неактивен
У Вас DELIMITER нигде не стоят, меня это и смущает. Смысл очень простой —
они ограничивают запросы. Если у Вас есть составной запрос, который нужно
отправить на сервер одним куском, то нужно клиенту сказать «те точки с запя-
той, которые я пишу, запрос не ограничивают, жди, когда наберу вот этот
ограничитель».
Наверное, примером проще:
[silentia] root test > CREATE PROCEDURE t () BEGIN SELECT 1; SELECT 2; END; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +---+ | 2 | +---+ | 2 | +---+ 1 row in set (0.00 sec) ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 1 [silentia] root test > \d ;; [silentia] root test > CREATE PROCEDURE t () BEGIN SELECT 1; SELECT 2; END;; Query OK, 0 rows affected (0.00 sec)
Тут видно, что клиент начал отправлять запросы, начиная с первой
точки с запятой, что приводит к ошибкам.
Что касается собаки — нет, она не означает глобальную переменную.
Вы можете использовать @любое_слово в качестве пользовательской
переменной, которая хранит произвольное скалярное значение. С сис-
темными переменными они никак не связаны. Есть, конечно, оговорка —
значения глобальных переменных можно читать, если поставить перед
названием переменной @@ (но при этом переменная всё равно без @@).
Неактивен
Спасибо, paulus.
1. Про DELIMITER по вашему примеру вроде понял, но тогда получается что мой код, где я создаю процедуру transfer_types не должен сработать? Он, как я понял, должен попытаться завершить запрос при первой встрече ';' (или после встречи), т.е. ругнуться на этой (или после) строчке:
Отредактированно kaurovis (28.01.2011 17:24:14)
Неактивен
1. Да, наверное, Ваш клиент умный. На мой взгляд, это страшно, я бы ему не доверял
Но у Вас может быть другой опыт.
2. Да, а вот если бы у Вас был менее умный клиент, он бы показал текст ошибки (кстати,
там же и нормальное название переменной указано)
[silentia] root test > call p(1); +------+------+ | a | t | +------+------+ | 1 | 1 | +------+------+ 1 row in set (0.00 sec) ERROR 1456 (HY000): Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p
3. Они отличаются тем, что var1 живет внутри процедуры и имеет тип INT,
а @var2 глобальная (т.е. после выхода из процедуры она будет жить до
конца сессии) и не типизированная.
4. Внутри SET операторы совпадают. Их различие проявляется внутри SELECT.
[silentia] root test > SET @a = 1; Query OK, 0 rows affected (0.00 sec) [silentia] root test > SELECT @a = 2, @a := 2; +--------+---------+ | @a = 2 | @a := 2 | +--------+---------+ | 0 | 2 | +--------+---------+ 1 row in set (0.00 sec)
Подсказка: первый нолик — это «ложь»
Неактивен
Спасибо, paulus.
Попробовал выполнить через phpMyAdmin, действительно ругается И про переменную тоже говорит
Вообще, это даже возмутительно, почему клиент не показывает ошибки, которые выдает ему сервер, особенно в случае с переменной. В случае с процедурами еще можно понять "сами поменяем разделитель, чтоб вам не париться".
Люди, не пользуйтесь "умными" клиентами, иначе придется выглядеть глупо!
А про собаку я все-таки прав был? "Она говорит о том, что переменная является глобальной в пределах одного запроса или сессии?"
И еще вопрос: если установить значение системной переменной, например
Неактивен
Ммм, да, наверное, я неправильно Вас понял. Это действительно пользовательская пере-
менная, действующая только на текущую сессию, и живущая до конца этой сессии.
Для меня же глобальная переменная — это переменная, которая действует на сервер в
целом. Попробую объяснить примером, заодно и на следующий вопрос отвечу
[silentia] root (none) > SELECT @@max_sp_recursion_depth; -- проверим текущее значение +--------------------------+ | @@max_sp_recursion_depth | +--------------------------+ | 0 | +--------------------------+ 1 row in set (0.00 sec) [silentia] root (none) > SET max_sp_recursion_depth = 255; -- установим локальное значение Query OK, 0 rows affected (0.00 sec) [silentia] root (none) > SELECT @@max_sp_recursion_depth; -- и проверим +--------------------------+ | @@max_sp_recursion_depth | +--------------------------+ | 255 | +--------------------------+ 1 row in set (0.00 sec) [silentia] root (none) > SET GLOBAL max_sp_recursion_depth = 20; -- а вот тут установим глобальную переменную Query OK, 0 rows affected (0.00 sec) [silentia] root (none) > SELECT @@max_sp_recursion_depth; -- локальное значение не изменилось +--------------------------+ | @@max_sp_recursion_depth | +--------------------------+ | 255 | +--------------------------+ 1 row in set (0.00 sec) [silentia] root (none) > \r -- пересоединимся с сервером Connection id: 46 Current database: *** NONE *** [silentia] root (none) > SELECT @@max_sp_recursion_depth; -- теперь локальное значение взято из глобальной переменной +--------------------------+ | @@max_sp_recursion_depth | +--------------------------+ | 20 | +--------------------------+ 1 row in set (0.00 sec)
То есть глобальное значение имеет смысл один раз прописать в конфигурации
сервера, и все локальные переменные будут инициализироваться глобальным
значением.
Неактивен