Задавайте вопросы, мы ответим
Вы не зашли.
Как объявить(а затем и создать) свое исключение в mysql.
Пробую
DECLARE NotEnoughMoney EXCEPTION; # объявление пользовательского исключения
...
...
...
IF Money<TrainingCost THEN
RAISE NotEnoughMoney;
Ругается на строчку с объявлением.
Неактивен
Используйте SIGNAL\RESIGNAL
http://dev.mysql.com/doc/refman/5.5/en/ … ignal.html
Неактивен
byterus написал:
Используйте SIGNAL\RESIGNAL
http://dev.mysql.com/doc/refman/5.5/en/ … ignal.html
Учитывайте, что фича доступна начиная с версии 5.5. В более ранних версиях для генерации исключения используются "народные методы", такие как, обращение к несуществующей таблице
Неактивен
Большое спасибо за ответы
Хочу спросить про "народный метод".
Объявлять ничего не надо. А там где надо создать исключительную ситуацию я обращаюсь к несуществующей таблице?
А потом ловлю исключение типа "Unkown Table" и выполняю нужный мне код.
Я правильно понял?
Неактивен
все правильно поняли
Неактивен
Я дописал в процедуре обращение к несуществующей таблице, при нехватки бюджета у клиента.
CREATE PROCEDURE WITHDRAWAL(IN ClientId INT (11), TrainingType TINYINT(1))
BEGIN
DECLARE TrainingNumber TINYINT(1); # Сколько раз уже отзанимался. После 10 раз даем 10% скидку.
DECLARE TrainingCost INT(5); # Стоимость тренировки: обычная(type=0) -- 10.000; с тренером(1) -- 30.000.
DECLARE Money INT(12); # Деньги клиента.
IF TrainingType>0 THEN
SELECT 30000 INTO TrainingCost;
ELSE
SELECT 10000 INTO TrainingCost;
END IF;
SELECT clients.Money INTO Money FROM clients
WHERE clients.Id = ClientId; # Проверка на платежеспособность клиента.
IF Money<TrainingCost THEN
SELECT * FROM notRealTable;
END IF;
SELECT COUNT(*) INTO TrainingNumber FROM timetable
WHERE timetable.ClientId = ClientId;
IF TrainingNumber>10 THEN
UPDATE clients SET Money = clients.Money - (TrainingCost - TrainingCost*0.10)
WHERE clients.Id = ClientId;
ELSE
UPDATE clients SET Money = clients.Money - TrainingCost
WHERE clients.Id = ClientId;
END IF;
END;
Сама процедура вроде нормально работает вызываю call: если денег у пользователя хватает -- списывается стоимость одной тренировки, если нет выдает ошибку ERROR 1146: Table notrealtable doesn't exist.
В триггере хочу обрабатывать исключение. Если у пользователя не оказалось денег, то тренировку надо "отменить", т.е. удалить созданную запись в таблице тренировок.
DELIMITER ;
CREATE TRIGGER 'myTrigger' AFTER INSERT ON 'timetable' FOR EACH ROW
BEGIN
DECLARE notTBL CONDITION FOR 1146;
DECLARE EXIT HANDLER FOR notTBL
BEGIN
DELETE FROM timetable WHERE Id = NEW.Id;
END;
call WITHDRAWAL(NEW.ClientId, NEW.TrainingType);
END;
Тестирую: добавляю новую запись в таблицу тренировок. Выдает 1415-Not allowed to return a result set from a trigger.
Вопрос 1. Где не прав? Может обращаться к несуществующей таблице надо по другому? Как правильно?.
Вопрос 2. Триггер. Думаю лучше было бы сделать before-триггер и в случае нехватки бюджета делать ROLLBACK? Зачем лишний раз записывать, а потом удалять запись. Попытался, но при создании триггера выскочило 1422 -Explicit or implicit commit is not allowed in stored function or trigger.
Неактивен
Используйте DROP non_exists_table, или CALL non_exists_procedure;
Отредактированно byterus (02.02.2010 14:42:20)
Неактивен
Спасибо. Теперь при добавлении записи в таблицу timetable, если денег не хватает другая ошибка: 1442 - Can't update table 'timetable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Т.е. строка добавилась, триггер сработал хочет ее(строку) удалить. Так нельзя? Как в тригере удалить(отменить процесс создания, если используется before триггер) строку, при неправильных данных?
Неактивен
Удалите несуществующую таблицу
Неактивен
Ёлки-палки) Я наконец-то понял.
Я в триггере ловлю исключение и пытаюсь отменить создание строки(которая и вызвала триггер). Мне нужно просто убрать обрабоку этой ошибки и она вылезет наружу и не даст строке добавиться.
Всем спасибо за помощь.
Неактивен
Вопрос по поводу синтаксиса, я уже всё пересмотрел. Ошибка и всё
Отредактированно fenya (28.03.2010 14:47:59)
Неактивен
Хм, мне казалось, что в 5.0 можно было удалять таблички. Ну, например, можете
заменить на INSERT INTO inexistent_table VALUES (1); В любом случае, это костыль
UPD: Как вариант — замените на DROP TEMPORARY TABLE, оно не откидывает транзакцию.
Неактивен