Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
PavelVX
Member

Откуда: Новосибирск
Сообщений: 211
Добрый день!
Подскажите, как выйти из ситуации, и главное, почему так?
Есть 2 процедуры, proc1 вызывается в proc2 (условно так):
proc1{
try

catch 
}
и процедура 2:
proc2{
begin tran
try
exec proc1
commit tran
catch
rollback tran
}

При ошибке в proc1 вызывается catch из нее же. Это правильно.
Ошибка неправильного приведения типа: строка приводится к числу.
Но при этом, почему-то, в proc2 выполнение тоже уходит в catch!
Почему? Я нигде не вызываю raiseerror. В блоке proc1.catch записываю, что возникла ошибка, и хочу продолжить выполнение proc2.
30 янв 17, 07:14    [20159888]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
PavelVX
Member

Откуда: Новосибирск
Сообщений: 211
Извиняюсь, забыл указать версию сервера: 11.0.5058.0 (х64)
30 янв 17, 07:15    [20159891]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31429
PavelVX
При ошибке в proc1 вызывается catch из нее же. Это правильно.
Ошибка неправильного приведения типа: строка приводится к числу.
Но при этом, почему-то, в proc2 выполнение тоже уходит в catch!
А у меня в proc2 выполнение не уходит в catch.
Выполните репро, может, у вас там ещё где то ошибка?
use tempdb
set nocount on
go
create procedure try_proc1
as
declare @i int, @s varchar(100) = 'asdf'
begin try
	print 'try_proc1_try 1'
	set @i=convert(int, @s)
	print 'try_proc1_try 2'
end try
begin catch
	print 'try_proc1_catch'
end catch
go
create procedure try_proc2
as
begin try
	print 'try_proc2_try 1'
	exec try_proc1
	print 'try_proc2_try 2'
end try
begin catch
	print 'try_proc2_catch'
end catch
go
exec try_proc2
go
drop procedure try_proc2
drop procedure try_proc1
30 янв 17, 09:02    [20160016]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
PavelVX
Member

Откуда: Новосибирск
Сообщений: 211
Вы правы, ваш тест проходит :(
Даже ошибка похожая.
try_proc2_try 1
try_proc1_try 1
try_proc1_catch
try_proc2_try 2
Сейчас буду пихать print везде и во всем. :(
30 янв 17, 09:52    [20160132]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
PavelVX
Member

Откуда: Новосибирск
Сообщений: 211
Немного локализировал ошибку, но это только еще больше запутало.
Довел ваш код под свою ситуацию, т.е. добавил транзакцию и все упало:
use tempdb
set nocount on
go
create procedure try_proc1
as
declare @i int, @s varchar(100) = 'asdf'
begin try
                print 'try_proc1_try 1'
                set @i=convert(int, @s)
                print 'try_proc1_try 2'
end try
begin catch
                print 'try_proc1_catch'
end catch
go
create procedure try_proc2
as
begin try
[b]begin tran[/b]
                print 'try_proc2_try 1'
                exec try_proc1
                print 'try_proc2_try 2'
[b]commit tran[/b]
end try
begin catch
[b]ROLLBACK TRAN[/b]
print 'try_proc2_catch'
declare @err_msg varchar(MAX) = 'Error: code (' + cast(ERROR_NUMBER() as varchar) + ') Message: (' + ERROR_MESSAGE() + ') ';
print @err_msg;
end catch
go
exec try_proc2
go
drop procedure try_proc2
drop procedure try_proc1

try_proc2_try 1
try_proc1_try 1
try_proc1_catch
try_proc2_try 2
try_proc2_catch
Error: code (3930) Message: (The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.)
30 янв 17, 13:48    [20161645]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
PavelVX,

только недавно было
там у вас XACT_STATE = -1 и на конверт выбивает всё

автор
Most conversion errors, for instance conversion of non-numeric string to a numeric value. BATCH
30 янв 17, 13:51    [20161687]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
PavelVX
Member

Откуда: Новосибирск
Сообщений: 211
Хех, понял.
Почитал, но так и не понял: как-то можно это обойти или нет?
30 янв 17, 14:16    [20161930]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
invm
Member

Откуда: Москва
Сообщений: 9397
PavelVX
как-то можно это обойти или нет?
Обойти что: ошибку конвертации или batch-aborting?
Первое можно - try_convert. Второе нельзя.
30 янв 17, 14:20    [20161964]     Ответить | Цитировать Сообщить модератору
 Re: вложенная процедура с try catch роняет вызывающую процедуру в catch, почему?  [new]
PavelVX
Member

Откуда: Новосибирск
Сообщений: 211
Большое спасибо!
Загнал преобразования в try_convert, все отработалось как надо!
Большое спасибо!
31 янв 17, 14:03    [20166083]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить