Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обработка ошибок в сохранённых процедурах. / 20 сообщений из 20, страница 1 из 1
25.07.2005, 19:42:14
    #33183656
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Есть процедура:
Код: plaintext
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.
CREATE PROCEDURE `Transfer_merchandise`(IN IN_Merchandise int, IN  In_AccountID int, IN  IN_Type int, IN IN_Date int)
    DETERMINISTIC
BEGIN
DECLARE a1,a2,a3,a4, IN_SenderID, IN_ReceiverID, IN_Money int DEFAULT  0 ;

CASE IN_Type
WHEN  0  then set IN_SenderID=In_AccountID; set IN_ReceiverID='1' ; set IN_Money=IN_Merchandise* 2500 ;
WHEN  1  then set IN_SenderID='1' ; set IN_ReceiverID=In_AccountID; set IN_Money=IN_Merchandise* 2500 ;
WHEN  2  then set IN_SenderID='1' ; set IN_ReceiverID=In_AccountID; set IN_Money=IN_Merchandise*(select  CASE `Level`
    WHEN  1  Then  2750 
    WHEN  2  Then  2890 
    WHEN  3  Then  3190 
    ELSE  0  END
    from tm_buildings where TeamID=In_AccountID and BuildingID= 2 );
/*else error;*/
End case;


start transaction;

update fn_accounts  set Money=Money-IN_Money where AccountID=IN_SenderID;
set a1=ROW_COUNT();
update fn_accounts  set Money=Money+IN_Money where AccountID=IN_ReceiverID;
set a2=ROW_COUNT();

update tm_merchandise set Merchandise=Merchandise+IN_Merchandise where AccountID=IN_SenderID;
set a3=ROW_COUNT();
update tm_merchandise set Merchandise=Merchandise-IN_Merchandise where AccountID=IN_ReceiverID;
set a4=ROW_COUNT();

if (a1= 1  and a2= 1  and a3= 1  and a4= 1 ) then commit; else rollback; [color=red]set @error='1064'; [/color]END IF;

END$$

Как обрабатывать передать запустившему, что процедура закончилась с ошибкой?
set @error='1064'; - неработает.
...
Рейтинг: 0 / 0
25.07.2005, 21:06:37
    #33183715
Astron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
O! Steven13, благодарю за пример, мне пригодился! А как сообщить - так просто, OUT или INOUT параметром процедуры. Или это не подходит под задачу?
...
Рейтинг: 0 / 0
25.07.2005, 23:32:30
    #33183789
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Нет, хочется что-бы движок сам обрабатывал.
...
Рейтинг: 0 / 0
25.07.2005, 23:37:50
    #33183793
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Хоть бери и целенаправленно вызывай неправильную функцию.

например:

Код: plaintext
 Select `dd` from `ddd`
...
Рейтинг: 0 / 0
26.07.2005, 11:02:54
    #33184304
Astron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Дока гласит -
"SIGNAL and RESIGNAL statements are not currently supported."
Но это не значит что так оно и есть в самом последнем билде, знаю я их...
Просто пока еще не весь процедурный язык слизали с DB2.
SIGNAL оно по-крайней мере распознает, только на остальной синтаксис оригинала ругается.
Тебе же остаются 3 варианта
- возвращать параметр,
- попробовать
DECLARE EXIT HANDLER FOR SQLSTATE VALUE ..... (должна вроде как вылететь за милую душу)
- искуственно вызывать нужную ошибку каким-нидь идиотским оператором, да...
...
Рейтинг: 0 / 0
26.07.2005, 19:55:10
    #33185785
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Astron

Несмог розобратся.
Можешь обяснить поподробней как это работает?
...
Рейтинг: 0 / 0
26.07.2005, 22:03:13
    #33185851
Astron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Вариант 1 - объяви процедуру как
create procedure myproc(out succ int)
begin
.............
if OK then
set succ=1;
else
set succ=0;
end if;
end|

и вызывай на здоровье
call myproc(@retvar);
Вариант 2 - с HANDLER - если непоймешь из родной доки, читай IBM-овскую на DB2, там подробнее. Слизано это оттуда. Не знаю правда, подойдет ли это к тебе под задачу, делает он не совсем то, алгоритм менять...
У IBM, в оригинале, есть оператор SIGNAL, как раз ставить нужный SQLSTATE. У майскуля пока нету, если верить доке. Может к релизу 5-й версии доделают, а может уже и сделали, а доку не поменяли. Говорят 5.0.6 уже вышла, у меня ее нет, проверить не на чем. Моя 5.0.2 SIGNAL все-таки распознает, но что ей надо после написать - не знаю.
Вариант 3 - вызвать ошибку специально, ломать не строить, косой оператор напиши. Только это криво. Правильно вариант 1. Процедура откатила транзакцию, вернула ошибку. Ты же хочешь чтобы она нагадила на уровень вверх, отсюда вопрос - а не бардачно ли распределена работа между процедурой и вызывающей ее частью софта....
Хотя вся проблема мне кажется непонятной
...
Рейтинг: 0 / 0
26.07.2005, 22:28:53
    #33185860
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
У меня 5.0.7.
Проблема в том, что процедура вызывается их XML, из разных страниц.
Очень нехочется ещё в придачу к сохранённой процедуре писать дополнительный код в каждую страницу. Лучше всё затолкать в неё.
...
Рейтинг: 0 / 0
27.07.2005, 21:10:39
    #33187951
Astron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Так и я про то же - надо все запихать в нее, так чтобы необходимость во внешней обработке пропала. Я так понимаю, есть желание на стороне клиента получить серверную ошибку, хотя ее нет, фактически это ошибка приложения. Увы, пока никак :-(
...
Рейтинг: 0 / 0
14.08.2005, 19:39:13
    #33214647
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Всё ещё интересует этот вопрос.
...
Рейтинг: 0 / 0
25.08.2005, 13:33:27
    #33234064
Валентин К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Мы отожгли это примерно так, как ты не хочешь делать.
т.е. в переменную ложим код ошибки, после выполнения процедуры ее обрабатываем 2-й процедурой, которая код ошибки приводит в текст по табличке ошибок.
Пока не добавлено распарсивание сведений в самих текстах, но чувствую, что уже нужно это реализовывать....

Тема интересная, хотелось бы узнать, что думает народ на эту тему.

А пользоваться исключениями - в MySQL - это риводит к неправильной работе процедур, уже попарился с этим. Да и человеческий текст практически не выведешь.

В MySQL нет механизна отправки клиенту произвольного исключения, типа как в ORACLE
...
Рейтинг: 0 / 0
26.08.2005, 02:23:03
    #33235159
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Валентин К

Решил проблему почти просто, через out параметр.
Вся хитрость в том кто это значение получает.

call myproc(@error);

А получает его переменная ошибки в XML.
Тоесть получилось почти красиво.

В переменную @error записует ошибку процедура, если в ней она исполнилась с ошибкой. Но если ошибка неявная, и процедура считает что её нет, она записует в @error=0, но нетут-то было, в исходящем параметре я передаю ошибку, и она напрямую попадает в переменную ошибки, и обработка прекращается.

Правда я незнаю, каким боком это может мне вылезти?
Что думаете по этому поводу?
...
Рейтинг: 0 / 0
26.08.2005, 17:21:14
    #33236814
Валентин К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Steven13 Валентин К

Решил проблему почти просто, через out параметр.
Вся хитрость в том кто это значение получает.

call myproc(@error);

А получает его переменная ошибки в XML.
Тоесть получилось почти красиво.

В переменную @error записует ошибку процедура, если в ней она исполнилась с ошибкой. Но если ошибка неявная, и процедура считает что её нет, она записует в @error=0, но нетут-то было, в исходящем параметре я передаю ошибку, и она напрямую попадает в переменную ошибки, и обработка прекращается.

Правда я незнаю, каким боком это может мне вылезти?
Что думаете по этому поводу?

Вобщем-то абсолютно все равно идет ли переменная out-параметром, либо просто переменной, т.к. все равно нужно после выполнения вызова CALL выполнить вызов SELECT @...

Посему мы просто завели зарезервированную переменную @OResult, в которую ложим код ошибки. Все положительные ошибки - выполнено успешно, все отрицательные - не выполнено. В зависимости от кода - вразумительный ответ.

Потом просто запросиком
select gf_Get_ErrorComments(), @OResult;
я просто извлекаю функцией текст и сам код ошибки соответственно. Дальше естественно все просто.

Извлечение идет по табличке сообщений, по типу ERR, вот собственно и все. Если не найдено описание, то берется "Невозможно выполнить операцию".

Вот далее пока не реализовывали, нет времени в основном...
Это просто более подробное описание действия.
Иначе реализации ошибок либо невозможны, либо глючат.
...
Рейтинг: 0 / 0
26.08.2005, 20:21:46
    #33237051
Steven13
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Нет всё просто.
Програма вылетает, ког-да в переменной @error появляется любое значение.
В процедуре в исходящий параметр вносится 0, если ошибки нет, и текст если есть ошибка.

Так-что больше ничего неприходится делать.
...
Рейтинг: 0 / 0
29.08.2005, 11:54:10
    #33238450
Валентин К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Steven13Нет всё просто.
Програма вылетает, ког-да в переменной @error появляется любое значение.
В процедуре в исходящий параметр вносится 0, если ошибки нет, и текст если есть ошибка.

Так-что больше ничего неприходится делать.

Программа вылетает потому что ты останавливаешь выполнение процедуры, насколько я понимаю. А останавливать ее выполнение не нужно, пиши более гибкую логику, а ошибки отлавливай в конце. Причем переменные хорошо ловятся на всех уровнях процедур.
Вобщем проблем с таким подходом найдено не было, отработали вполне нормально.
Т.к. этот вопрос был поднят сразу при проектировании, то и бизнеслогика писалась в соответствии с ошибками. Все ошибки ищатся самими процедурами, а не генерируются сервером, а потом либо выполнение идет на другие уровни, либо пропускается и выходит с кодом ошибки в переменной.
Такой вариан не подходит?
...
Рейтинг: 0 / 0
01.11.2005, 10:45:01
    #33354609
KPH
KPH
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
День добрый,
Подскажите пожалуста как корректно организовать обработку ошибок (НЕ пользовательских) в хранимых процедурах с тем чтобы при ошибке откатить начатую в процедуре транзакцию и при этом вернуть через OUT параметр код возникшей ошибки. Я немогу найти функцию или переменную через которые пожно было бы узнать код ошибки. Получается что для каждого варианта ошибки нужно писать чтото вроде:

DECLARE EXIT HANDLER FOR 1061
BEGIN
my_err=1062;
ROLLBACK;
END;

Т.Е. каждая процедура в которой я хочу отловить и вернуть код ошибки
должна содержать столько таких выражений сколько я предполагаю возможных в ней ошибок:
---------------------------------------------
CREATE PROCEDURE p1(OUT my_err INTEGER)
BEGIN
......
DECLARE EXIT HANDLER FOR 1061
BEGIN
my_err=1062;
ROLLBACK;
END;
DECLARE EXIT HANDLER FOR 1062
BEGIN
my_err=1062;
ROLLBACK;
END;
....
и.т. далее
....
/*логика процедуры*/
....
END
----------------------------------------------
Как то очень не красиво получается. Может обработчик хоть както можно вынести в отдельную функцию.

Заранее спасибо.
При исполь
...
Рейтинг: 0 / 0
02.11.2005, 10:57:38
    #33356868
KPH
KPH
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
интересная инфа по этой теме
http://forums.mysql.com/read.php?98,31753,31753#msg-31753
...
Рейтинг: 0 / 0
04.11.2005, 12:23:04
    #33361589
Валентин К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Для транзакций нужно использовать транзакционный движок.

Далее нужно понимать, что объявив хендлер выхода процедура не будет выполнена до конца и rollback, который в конце болтается естественно не будт запущен. И если включено автосомитование транзакций, то вызванная ошибка не откатит транзакцию, а запостит ее.

В нащей реализации процедуры внешнего уровня имеют такую структуру

...
BEGIN
START TRANSACTION;
...
/*Тескт процедуры*/
IF @OResult<0 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END;

Транзакции работают правильно, т.к. не однократно тестировали.
...
Рейтинг: 0 / 0
05.11.2005, 12:27:11
    #33362437
KPH
KPH
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
Спасибо за ответ, но если честно я немного вас не понял.
Вы после каждой произведеной опереции (Insert? update...) проверяете ожидаемое кол-во возвращаемых запросом строк (типа ROW_COUNT()) и записываете результат в переменную @OResult и перед завершением процедуры анализируете ее и производите соответсвенно откат или подтверждение транзакции?
...
Рейтинг: 0 / 0
05.11.2005, 12:29:23
    #33362438
KPH
KPH
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка ошибок в сохранённых процедурах.
не моглибы Вы пояснить что такое процедура внешнего уровня. Спасибо.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обработка ошибок в сохранённых процедурах. / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]