SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 02.02.2010 12:16:53

bldbld
Участник
Зарегистрирован: 31.01.2010
Сообщений: 9

Обработка исключений в Mysql

Как объявить(а затем и создать) свое исключение в mysql.

Пробую
 
DECLARE NotEnoughMoney EXCEPTION;  # объявление пользовательского исключения
...
...
...

  IF Money<TrainingCost THEN 
    RAISE NotEnoughMoney;

Ругается на строчку с объявлением.

Неактивен

 

#2 02.02.2010 12:19:41

byterus
ISV
MySQL Ready Partner
Зарегистрирован: 02.02.2010
Сообщений: 39

Re: Обработка исключений в Mysql

Используйте SIGNAL\RESIGNAL
http://dev.mysql.com/doc/refman/5.5/en/ … ignal.html

Неактивен

 

#3 02.02.2010 12:31:51

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Обработка исключений в Mysql

byterus написал:

Используйте SIGNAL\RESIGNAL
http://dev.mysql.com/doc/refman/5.5/en/ … ignal.html

Учитывайте, что фича доступна начиная с версии 5.5. В более ранних версиях для генерации исключения используются "народные методы", такие как, обращение к несуществующей таблице

Неактивен

 

#4 02.02.2010 12:38:29

bldbld
Участник
Зарегистрирован: 31.01.2010
Сообщений: 9

Re: Обработка исключений в Mysql

Большое спасибо за ответы
Хочу спросить про "народный метод".
  Объявлять ничего не надо. А там где надо создать исключительную ситуацию я обращаюсь к несуществующей таблице?
  А потом ловлю исключение типа "Unkown Table"  и выполняю нужный мне код.

Я правильно понял?

Неактивен

 

#5 02.02.2010 12:39:44

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Обработка исключений в Mysql

все правильно поняли

Неактивен

 

#6 02.02.2010 14:35:17

bldbld
Участник
Зарегистрирован: 31.01.2010
Сообщений: 9

Re: Обработка исключений в Mysql

Я дописал в процедуре обращение к несуществующей таблице, при нехватки бюджета у клиента.


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.

Неактивен

 

#7 02.02.2010 14:40:37

byterus
ISV
MySQL Ready Partner
Зарегистрирован: 02.02.2010
Сообщений: 39

Re: Обработка исключений в Mysql

Используйте DROP non_exists_table, или CALL non_exists_procedure;

Отредактированно byterus (02.02.2010 14:42:20)

Неактивен

 

#8 02.02.2010 17:29:48

bldbld
Участник
Зарегистрирован: 31.01.2010
Сообщений: 9

Re: Обработка исключений в Mysql

Спасибо. Теперь при добавлении записи в таблицу 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 триггер) строку, при неправильных данных?

Неактивен

 

#9 02.02.2010 18:07:07

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Обработка исключений в Mysql

Удалите несуществующую таблицу smile

Неактивен

 

#10 02.02.2010 18:41:28

bldbld
Участник
Зарегистрирован: 31.01.2010
Сообщений: 9

Re: Обработка исключений в Mysql

Ёлки-палки) Я наконец-то понял.
Я в триггере ловлю исключение и пытаюсь отменить создание строки(которая и вызвала триггер). Мне нужно просто убрать обрабоку этой ошибки и она вылезет наружу и не даст строке добавиться.
Всем спасибо за помощь.

Неактивен

 

#11 28.03.2010 14:13:25

fenya
Участник
Зарегистрирован: 28.03.2010
Сообщений: 1

Re: Обработка исключений в Mysql

Вопрос по поводу синтаксиса, я уже всё пересмотрел. Ошибка и всё

CREATE TRIGGER plsch BEFORE INSERT ON `plan-schedule`
FOR each
ROW
BEGIN
IF NOT
EXISTS (

SELECT idDiscipline
FROM plan, `plan-schedule` , inserted
WHERE plan.id = `plan-schedule`.id_plan
AND `plan-schedule`.`id_schedule` = `inserted`.`id_schedule`
AND idDiscipline = (
SELECT idDiscipline
FROM plan, `plan-schedule`
WHERE `plan-schedule`.`id_schedule` = `inserted`.`id_schedule` )
)
BEGIN
DROP tablenot END END


#1064 - 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 'BEGIN drop tablenot END END' at line 9

Решил проблему синтаксиса
Но теперь

CREATE TRIGGER plsch after insert on `plan-schedule` for each row
BEGIN
IF NOT EXISTS(
select idDiscipline from plan,`plan-schedule`,inserted
where plan.id=`plan-schedule`.id_plan and `plan-schedule`.`id_schedule`=`inserted`.`id_schedule`
and idDisciplineselect idDiscipline from plan,`plan-schedule`
where `plan-schedule`.`id_schedule`=`inserted`.`id_schedule`)
)
THEN
drop table tablenot;
END IF;
END;
 


ERROR 1422 (HY000): Explicit or implicit commit is not allowed in stored function or trigger.

Отредактированно fenya (28.03.2010 14:47:59)

Неактивен

 

#12 28.03.2010 23:19:28

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Обработка исключений в Mysql

Хм, мне казалось, что в 5.0 можно было удалять таблички. Ну, например, можете
заменить на INSERT INTO inexistent_table VALUES (1); В любом случае, это костыль sad

UPD: Как вариант — замените на DROP TEMPORARY TABLE, оно не откидывает транзакцию.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson