|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
Adaptive Server Enterprise/12.5.4/EBF 15447 ESD#8/P/x86_64/Enterprise Linux/ase1254/2105/64-bit/OPT/Sat Mar 22 04:13:57 2008 Просветите, пожалуйста: как распознать факт наличия ошибки (exception). Почему-то @@transtate и @@error не показывают этого факта (раньше вроде работало...) Вот такой код запускается через isql: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Внутри ХП SLIVFreeRest_fal происходит exception, но в этом вызывающем коде после завершения ХП @@transtate = 0 и @@error = 0 Так что в любом случае происходит выполнение commit-a ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2017, 20:13 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
Lysyi, Факт ошибки: @@error != 0 @@transtate в ловле исключений не поможет. А в остальном - смотри на свою хранимую процедуру, действительно ли она посылает исключение? Уверен? Точно-точно? А в скрипте который отдается в isql есть строка go? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2017, 00:45 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
White Owl, Насчёт исключения - да я уверен, это исключение пишется в вывод в файл, вот так это выглядит: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
(на саму ошибку не смотри: не в ней дело, её легко исправить - вопрос принципа, это не единственное потенциально возможное исключение) Насчёт @@error - здесь же фиксируется результат выполнения последнего оператора. После оператора, вызвавшего исключение выполняются другие операторы, которые сбрасывают @@error в ноль. Да что говорить, наверное сам вызов exec SLIVFreeRest_fal и сбрасывает @@error Я тут больше на @@transtate надеялся - исключение же внутри транзакции происходит Насчёт go - да, в скрипте go есть. Из скрипта вызывается много процедур, каждая в своём пакете (go). Но вот конкретный приведённый код, он внутри одной из этих процедур (NewDate) и в процедуре никаких go, конечно, нету ... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2017, 15:06 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
LysyiНасчёт исключения - да я уверен, это исключение пишется в вывод в файл, вот так это выглядит: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
(на саму ошибку не смотри: не в ней дело, её легко исправить - вопрос принципа, это не единственное потенциально возможное исключение) А вот это и есть твоя ошибка - что ты не смотришь на саму ошибку. У сервера есть собственное понятие что такое fatal и nonfatal error. Те ошибки что считаются сервером за nonfatal - не обрывают хранимую процедуру и не будут отловлены твоим кодом (но попадут в лог isql). В данном случае (авто-закрытие курсора и попытка чтения из закрытого курсора), это не исключение приводящее к прерыванию процедуры, а предупреждение которое можно игнорировать без особых проблем для самой базы данных (в смысле не нарушается целостность заявленная через unique/check/foreign key/etc). Проблемы с курсором - не приводят к остановке хранимой процедуры. Чтобы обрывать ХП и отлавливать это через @@error как ты показывал в первом посте надо или совершать "страшные" ошибки (которые fatal с точки зрения сервера) или кидать исключения вручную при помощи команды raiserror. Подробнее про ошибки читать тут: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc38151.1510/html/iqrefbb/iqrefbb638.htm LysyiЯ тут больше на @@transtate надеялся - исключение же внутри транзакции происходит@@transtate=0 - ошибок нет. @@transtate=1 коммит отработал успешно. А ошибки транзакции ( @@transtate=2 или 3), будут только если команды insert/update/delete были прерваны по какой-то причине. Нарушение уникальности в индексе например (может быть и 2 и 3). А чтобы устойчиво получать 3-ку, надо например запускать долгоиграющую команду типа удалить все записи из таблицы с миллиардом строк, а пока она выполняется зайти как администратор и отменить команду - тогда юзер отдавший команду почти наверняка получит @@transtate=3 ... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2017, 18:17 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
Я со всем заранее согласен и благодарен за участие, но вопрос остаётся: как поймать ошибку, произошедшую где-то в глубине вызванной процедуры в SQL-коде, вызвавшей эту процедуру. Готов на всё - скажите только что делать. Реакция системы на ошибку определяется её уровнем серьёзности. Не удачный, конечно, пример с курсором, но это субъективно. Объективно в данном случае Level 16, то есть это самая обычная ошибка (raiserror тоже даёт Level 16), недостаточная для того, чтобы оборвать выполнение, но достаточная для того, чтобы вызвать исключение. При вызове этой ХП из кода приложения (если begin tran / commit / rollback делает приложение), Exception прекрасно ловится и происходит откат. А если вызывать из SQL-кода, то ошибки(исключения) не видно. Наверное так же быть не должно, должен же быть способ... Проверил: вставил в начале SLIVFreeRest_fal raiserror - результат тот же: после exec сразу @@transtate = 0 и @@error = 0, хотя мой текст из raiserror исправно печатается в лог. То же самое было у меня с другой ХП, в которой ошибка была при выполнении update (просто я её уже исправил, поэтому затруднительно её здесь привести). Ну, строго говоря, там не было нарушения уникальности в индексе, но там было вполне аналогичное нарушение: срабатывала проверка в тргигере и процесс прерывался через ROLLBACK TRIGGER WITH RAISERROR ... RETURN Результат тот же: после exec сразу @@transtate = 0 и @@error = 0 Ну я, конечно смоделирую нарушение уникальности в индексе (проверить), но думаю, будет то же самое - во всех этих случаях генерируется исключение с Level = 16 ... |
|||
:
Нравится:
Не нравится:
|
|||
20.10.2017, 19:37 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
LysyiЯ со всем заранее согласен и благодарен за участие, но вопрос остаётся: как поймать ошибку, произошедшую где-то в глубине вызванной процедуры в SQL-коде, вызвавшей эту процедуру. Готов на всё - скажите только что делать. Всё очень просто. И одновременно очень сложно. После КАЖДОГО оператора КАЖДОЙ процедуры нужно проверять @@error и @@rowcount на наличие ошибок и неожидаемого поведения. Если ошибка обнаружена, её надо соотв. образом обрабатывать. P.S. напомню, что именно исключений в ASE нет. Есть только ошибки. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2017, 13:57 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
LysyiРеакция системы на ошибку определяется её уровнем серьёзности. Не удачный, конечно, пример с курсором, но это субъективно. Объективно в данном случае Level 16, то есть это самая обычная ошибка (raiserror тоже даёт Level 16), недостаточная для того, чтобы оборвать выполнение, но достаточная для того, чтобы вызвать исключение. При вызове этой ХП из кода приложения (если begin tran / commit / rollback делает приложение), Exception прекрасно ловится и происходит откат. А если вызывать из SQL-кода, то ошибки(исключения) не видно. Наверное так же быть не должно, должен же быть способ... Ещё раз, о каких исключениях ты всё время ведёшь речь? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2017, 13:59 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
MasterZivПосле КАЖДОГО оператора КАЖДОЙ процедуры нужно проверять @@error и @@rowcount на наличие ошибок и неожидаемого поведения. Если ошибка обнаружена, её надо соотв. образом обрабатывать. P.S. напомню, что именно исключений в ASE нет. Есть только ошибки. Поддержу. Хоть и в ASA, но постоянно применял такую практику внутри процедур, для каждого оператора, который может привести к ошибке, с точки зрения бизнес-логики - обязательно, с точки зрения сервера или базы выборочно, по ситуации. Зато на выходе из процедуры по коду возврата и сообщению четко понимаешь что происходит. Помогает как для разработчика так и для культурного оповещения пользователю, администратору и т.д. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2017, 16:04 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
MasterZivЕщё раз, о каких исключениях ты всё время ведёшь речь? Ну раз нет в Sybase исключений, то получается, что ни о каких... Вообще я имел в виду, что когда приложение вызывает SQL-код и в этом SQL-коде происходит хоть какая-то ошибка с уровнем серьёзности выше 10 (кажется 10, точно не помню), то приложение создаёт объект класса Exception (TException и т.п.). Факт возникновения такого объекта ловится в блоке try и управление передаётся коду, отвечающему за обработку ошибки (откат транзакции, вывод сообщения и т.п.). Проверять @@error после каждого оператора не нужно. Это работает и с Sybase, т.е. строго, наверное, нельзя говорить, что в Sybase исключений совсем нет. Ну ещё я имел в виду, что в MS SQL есть исключения и даже блок try в TSQL предусмотрен. Вроде СУБДы из одного корня растут. Так-то что... Спасибо, коллеги, понятно. На нет и суда нет :( Но вообще, конечно, странно! После каждого оператора @@error проверять это как-то несовременно что-ли. У меня тут километры кода - всё перелопатить нереально. Но главное даже не это: потенциально ошибка может произойти где угодно (даже то, что быть не может очень даже может быть). Странно, что нету способа отловить любую ошибку, где бы она внутри транзакции не произошла ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2017, 18:19 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
LysyiСтранно, что нету способа отловить любую ошибку, где бы она внутри транзакции не произошлаНу почему же нет? Есть. Только не в TSQL :) Нужно будет отказаться от isql. И заменит его собственной скрипто-запускалкой. Просто создаешь глобальный флаг "была ошибка", и в колбеках устанавливаешь его. Что-то в духе Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Ну а если пишешь на Си, то можно вместо колбеков использовать ct_diag() в нужных местах. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2017, 22:08 |
|
Не работают @@transtate и @@error - как поймать ошибку?
|
|||
---|---|---|---|
#18+
Lysyi Проверять @@error после каждого оператора не нужно. Это работает и с Sybase, т.е. строго, наверное, нельзя говорить, что в Sybase исключений совсем нет. Нужно. Именно потому, что исключений нет. Но есть и ещё один аспект , например, у тебя такой код: Код: sql 1.
Ты его выполняешь, и как ты думаешь, что будет в переменной @@error , если пользователя с таким name не будет в твоей БД? Вот. LysyiНу ещё я имел в виду, что в MS SQL есть исключения и даже блок try в TSQL предусмотрен. Да, по ошибкам БД тебе вылетит исключение, по raiserror тоже, но что тебе прилетит в вышеуказанном случае ? Опять, ничего. Это не системная ошибка уровня БД, это ошибка в логике приложения уже. LysyiПосле каждого оператора @@error проверять это как-то несовременно что-ли. У меня тут километры кода - всё перелопатить нереально. Но главное даже не это: потенциально ошибка может произойти где угодно (даже то, что быть не может очень даже может быть). Странно, что нету способа отловить любую ошибку, где бы она внутри транзакции не произошла Ну, вот так вот, других рецептов нет (в смысле не существует). ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2017, 18:09 |
|
|
start [/forum/topic.php?fid=55&msg=39539147&tid=2009641]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
51ms |
get topic data: |
13ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
2ms |
others: | 250ms |
total: | 408ms |
0 / 0 |