powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Обработка ошибок в сохранённых процедурах.
20 сообщений из 20, страница 1 из 1
Обработка ошибок в сохранённых процедурах.
    #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
Обработка ошибок в сохранённых процедурах.
    #33183715
Astron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
O! Steven13, благодарю за пример, мне пригодился! А как сообщить - так просто, OUT или INOUT параметром процедуры. Или это не подходит под задачу?
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #33183789
Steven13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, хочется что-бы движок сам обрабатывал.
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #33183793
Steven13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хоть бери и целенаправленно вызывай неправильную функцию.

например:

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

Несмог розобратся.
Можешь обяснить поподробней как это работает?
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #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
Обработка ошибок в сохранённых процедурах.
    #33185860
Steven13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня 5.0.7.
Проблема в том, что процедура вызывается их XML, из разных страниц.
Очень нехочется ещё в придачу к сохранённой процедуре писать дополнительный код в каждую страницу. Лучше всё затолкать в неё.
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #33187951
Astron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так и я про то же - надо все запихать в нее, так чтобы необходимость во внешней обработке пропала. Я так понимаю, есть желание на стороне клиента получить серверную ошибку, хотя ее нет, фактически это ошибка приложения. Увы, пока никак :-(
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #33214647
Steven13
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё ещё интересует этот вопрос.
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #33234064
Фотография Валентин К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мы отожгли это примерно так, как ты не хочешь делать.
т.е. в переменную ложим код ошибки, после выполнения процедуры ее обрабатываем 2-й процедурой, которая код ошибки приводит в текст по табличке ошибок.
Пока не добавлено распарсивание сведений в самих текстах, но чувствую, что уже нужно это реализовывать....

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

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

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

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

call myproc(@error);

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

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

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

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

call myproc(@error);

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

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

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

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

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

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

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

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

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

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

Программа вылетает потому что ты останавливаешь выполнение процедуры, насколько я понимаю. А останавливать ее выполнение не нужно, пиши более гибкую логику, а ошибки отлавливай в конце. Причем переменные хорошо ловятся на всех уровнях процедур.
Вобщем проблем с таким подходом найдено не было, отработали вполне нормально.
Т.к. этот вопрос был поднят сразу при проектировании, то и бизнеслогика писалась в соответствии с ошибками. Все ошибки ищатся самими процедурами, а не генерируются сервером, а потом либо выполнение идет на другие уровни, либо пропускается и выходит с кодом ошибки в переменной.
Такой вариан не подходит?
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #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
Обработка ошибок в сохранённых процедурах.
    #33356868
KPH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
KPH
Гость
интересная инфа по этой теме
http://forums.mysql.com/read.php?98,31753,31753#msg-31753
...
Рейтинг: 0 / 0
Обработка ошибок в сохранённых процедурах.
    #33361589
Фотография Валентин К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для транзакций нужно использовать транзакционный движок.

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

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

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

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


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