Гость
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch / 9 сообщений из 9, страница 1 из 1
16.05.2016, 12:05
    #39236399
Stalker4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
Hi All,

Sybase SA 12.0.1

Есть SP:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create procedure dba.TestSP(in nID integer)
begin

 if nID = -1 then
   raiserror 19001 'Ошибка в SP'
   return;
 end if; 

 insert into dba.TEST(ID) values(nID);

end;


В коде программы на сервер посылается sql-batch:

Код: sql
1.
2.
 call dba.TestSP(-1);
 insert into dba.TEST2(...) values(...);



Так вот, несмотря на то, что в SP срабатывает raiserror, вставка в TEST2 все равно происходит.

Хотя если на таблицу TEST повесить триггер в котором вызвать raiserror или просто при вставки в таблицу TEST произойдет системная ошибка (например -196), то тогда выполнении sql-batch прерывается, и вставка в таблицу TEST2 не происходит.

Вопрос: Почему такая разница по прерыванию выполнения sql-batch, в зависимости от того, где именно произошла ошибка ?
Можно ли что то сделать, что бы в приведенном выше примере при возникновении ошибки в SP, sql-batch прервался и вставки в таблицу TEST2 не было бы ?

Пока я нашел только один выход - использование @@error

Код: sql
1.
2.
3.
 call dba.TestSP(-1);
 if @@error <> 0 then return endif;
 insert into dba.TEST2(...) values(...);


Но этот вариант меня смущает использованием @@error - ведь вроде бы эта переменная относится к диалекту Transact-SQL, а я работаю с диалектом Watcom SQL ...
...
Рейтинг: 0 / 0
16.05.2016, 13:38
    #39236511
old_joy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
Используйте лучше конструкцию

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create procedure dba.TestSP(in nID integer)
begin

declare no_primary_key_value exception for sqlstate value '19001';

 if nID = -1 then
   message 'Ошибка в SP' type action to client;
   signal no_primary_key_value

 end if; 

 insert into dba.TEST(ID) values(nID);

end;
...
Рейтинг: 0 / 0
16.05.2016, 18:41
    #39236858
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
Stalker4В коде программы на сервер посылается sql-batch:

Код: sql
1.
2.
 call dba.TestSP(-1);
 insert into dba.TEST2(...) values(...);



Так вот, несмотря на то, что в SP срабатывает raiserror, вставка в TEST2 все равно происходит.Ну правильно все происходит. Пакет команд, это пакет команд. Это не одна команда. :)
Иными словами, пакет не обязан прерываться если первая команда завершилась с ошибкой. Это целиком на совести клиента отсылающего команды на сервер.
Если говорить о механике процесса, то клиент отсылая на сервер пакет заполняет "командный буфер соединения", сервер читает из него пока синтаксический анализатор не скажет что команда прочитана, сервер выполняет эту команду и кладет результат команды в "буфер результата", потом сервер читает следующую команду из "командного буфера"... В конце клиент получает все что есть в "буфере результата" за раз. Если там несколько резалтсетов вперемешку с несколькими ошибками - значит так оно и будет. Но это чтение результатов будет уже в конце всего пакета.
В частности, если ты сейчас пошлешь пакет:
Код: sql
1.
2.
call dba.TestSP(-1);
call dba.TestSP(-1);


Ты должен получить две ошибки подряд.
Но учти, что dbisql выдаст первую ошибку и остановится, потому что он самостоятельно режет пакет на команды и посылает их на сервер по отдельности.

Ну а чтобы превратить пакет в одну большую команду, ты либо должен сам с клиента резать пакет на команды (и проверять на возникновение ошибок), либо обернуть вызов всего пакета в begin atomic/end скобки.
...
Рейтинг: 0 / 0
17.05.2016, 09:49
    #39237102
Stalker4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
old_joyИспользуйте лучше конструкцию

Код: sql
1.
2.
3.
4.
5.
declare no_primary_key_value exception for sqlstate value '19001';
 if nID = -1 then
   message 'Ошибка в SP' type action to client;
   signal no_primary_key_value
 end if; 


Вопрос: Чем данная конструкция лучше прямого вызова raiserror ?
И кстати, а разве после signal, не надо указать return, что бы прервать выполнение SP ?

White OwlНу а чтобы превратить пакет в одну большую команду, ты либо должен сам с клиента резать пакет на команды (и проверять на возникновение ошибок), либо обернуть вызов всего пакета в begin atomic/end скобки.
Попробовал вариант с begin atomic/end - не работает, так как вставка в TEST2 все равно происходит.

Резать пакет на команды можно, но это усложнение кода клиента.

Пока я все же остановлюсь на варианте использования прокладки в виде
Код: sql
1.
if @@error <> 0 then return endif

между командами пакета, единственное что меня немного смущает (про это я написал в первом сообщении) @@error - ведь вроде бы эта переменная относится к диалекту Transact-SQL, а я работаю с диалектом Watcom SQL ... Или насчет @@error я не прав ?

White OwlНу правильно все происходит. Пакет команд, это пакет команд. Это не одна команда.Это то понятно и вопросов бы не было, если бы не одно НО:
если на таблицу TEST повесить триггер в котором вызвать raiserror или просто при вставки в таблицу TEST произойдет системная ошибка (например -196), то тогда выполнении sql-batch прерывается, и вставка в таблицу TEST2 не происходит.
Вопрос: Почему такая разница по прерыванию выполнения sql-batch, в зависимости от того, где именно произошла ошибка ?
...
Рейтинг: 0 / 0
17.05.2016, 18:33
    #39237709
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
Stalker4old_joyИспользуйте лучше конструкцию

Код: sql
1.
2.
3.
4.
5.
declare no_primary_key_value exception for sqlstate value '19001';
 if nID = -1 then
   message 'Ошибка в SP' type action to client;
   signal no_primary_key_value
 end if; 


Вопрос: Чем данная конструкция лучше прямого вызова raiserror ? Raiserror и siganl это хоть и родственные штуки, но пришедшие из разных диалектов. Судя по точкам с запятой, ты предпочитаешь использовать Watcom, так что signal будет лучше... меньше неожиданностей изза переключений диалектов.

Stalker4White OwlНу а чтобы превратить пакет в одну большую команду, ты либо должен сам с клиента резать пакет на команды (и проверять на возникновение ошибок), либо обернуть вызов всего пакета в begin atomic/end скобки.
Попробовал вариант с begin atomic/end - не работает, так как вставка в TEST2 все равно происходит.Ну да, это как раз диалектные проблемы, raiserror это наследие Transact'а и оно ближе по сути к Watcom'овскому message to. В смысле это просто push сообщение на клиента, но не ошибка выполнения. А begin atomic это Watcom пакеты и их надо прерывать через signal/exception. Там тот же принцип работы что исключения в ООП языках.
Читай тут:
http://infocenter.sybase.com/help/topic/com.sybase.help.sqlanywhere.12.0.0/dbusage/ptstas.html
http://infocenter.sybase.com/help/topic/com.sybase.help.sqlanywhere.12.0.0/dbusage/pteweh.html

Stalker4Резать пакет на команды можно, но это усложнение кода клиента.Зато больше контроля :)

Stalker4единственное что меня немного смущает (про это я написал в первом сообщении) @@error - ведь вроде бы эта переменная относится к диалекту Transact-SQL, а я работаю с диалектом Watcom SQL ... Или насчет @@error я не прав ?Прав. По существу, у тебя все-же Transact а не Watcom получается.

Stalker4если на таблицу TEST повесить триггер в котором вызвать raiserror или просто при вставки в таблицу TEST произойдет системная ошибка (например -196), то тогда выполнении sql-batch прерывается, и вставка в таблицу TEST2 не происходит.
Вопрос: Почему такая разница по прерыванию выполнения sql-batch, в зависимости от того, где именно произошла ошибка ?Потому что raiserror внутри триггера вызывает ошибку сервера. Это легальный метод отменить команду унаследованный из ASE. Но сам по себе raiserror не является ошибкой сервера. Слегка запутанно, но увы.
...
Рейтинг: 0 / 0
18.05.2016, 11:01
    #39238021
Stalker4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
White OwlStalker4
Код: sql
1.
2.
3.
4.
5.
declare no_primary_key_value exception for sqlstate value '19001';
 if nID = -1 then
   message 'Ошибка в SP' type action to client;
   signal no_primary_key_value
 end if; 


Вопрос: Чем данная конструкция лучше прямого вызова raiserror ? Raiserror и siganl это хоть и родственные штуки, но пришедшие из разных диалектов. Судя по точкам с запятой, ты предпочитаешь использовать Watcom, так что signal будет лучше... меньше неожиданностей изза переключений диалектов.
Поигрался я с этой конструкцией.
Предварительно хочу сказать что клиент у меня на Delphi, который посредство библиотеки SQL Direct (через ODBC-драйвер) работает с базой.

Действительно, при использовании signal прерывания выполнения блока кода происходит сразу (в том числе и прерывания выполнение текущей SP без необходимости указывать return) и даже без обертывания в begin atomic ... end.

НО:

При выполнении signal, в программе (на компе клиента) сначала появляется окно с пустым заголовком и моим текстом сообщения об ошибке, причем это окно не моей программы, а похоже от самого ODBC-драйвера, соответственно я в коде своей программы вообще не могу отловить это сообщение. И только после закрытия этого окна, эта ошибка попадает в мою программу, НО с кодом -237 ("Сигнал об исключении, определенном пользователем"), а мой код ошибки надо вылавливать не в свойстве класса ошибки ErrorCode, а в свойстве SQLState. А заданный мной текст ошибки вообще в коде программы для его обработки не доступен.

И если появления странного окна с пустым заголовком еще можно убрать, изменив для message значение action на info (или вообще убрать TYPE), то как выцепить на клиенте текст моей ошибки в этом случае вообще не понятно.
Вопрос: Как это можно сделать при использовании signal ?
...
Рейтинг: 0 / 0
18.05.2016, 17:49
    #39238530
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
Нуууу.... тут я уже скорее всего не помогу.
Во времена онные, я вполне успешно делал это на чистом ODBC (из Си в смысле). Не знаю как это будет выглядеть в Дельфях.
...
Рейтинг: 0 / 0
18.05.2016, 20:56
    #39238621
Sergey Orlov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
Stalker4Поигрался я с этой конструкцией.
Предварительно хочу сказать что клиент у меня на Delphi, который посредство библиотеки SQL Direct (через ODBC-драйвер) работает с базой.

А вы поищите компоненты прямого доступа от Гаврилова С., может они получше... Если заинтересуетесь и не найдете киньте мне в личку, я попробую списаться с автором... Правда последняя версия у него была для asa9, но я думаю это не проблематично...
...
Рейтинг: 0 / 0
19.05.2016, 10:17
    #39238811
Stalker4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch
White OwlНуууу.... тут я уже скорее всего не помогу.Ну в любом случае, спасибо Вам за помощь, основной мой вопрос Вы прояснили.

Sergey OrlovStalker4Поигрался я с этой конструкцией.
Предварительно хочу сказать что клиент у меня на Delphi, который посредство библиотеки SQL Direct (через ODBC-драйвер) работает с базой.
А вы поищите компоненты прямого доступа от Гаврилова С., может они получше... Если заинтересуетесь и не найдете киньте мне в личку, я попробую списаться с автором... Правда последняя версия у него была для asa9, но я думаю это не проблематично...Это Вы случайно не про SaVCL речь ведете ? У меня валяется её старая версия 2.08 (от 2004 года).
Сайт программы живой, последняя версия там 2.6 для XE - правда она уже платная.
Но в любом случае спасибо за предложение, но не надо - из за такой ерунды менять движок ИМНО не стоит. Проще остаться на raiserror, тем более что она вполне нормально работает (за исключением некоторых особенностей).

P.S. Если говорить о библиотеках прямого доступа, то я раньше работал с NativeDB, но потом ушел с нее на SQL Direct.
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Sybase SA 12: Странная разница обработки ошибки при выполнении SQL-batch / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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