Убрать TRY-CATCH
, если возможно - разделить операторы скриптов на несколько отдельных партий с GO
.
TRY-CATCH
реагирует на первое исключение и нарушает выполнение TRY-блока:
Если ошибка происходит в блоке TRY, управление передается в другую группу операторов, которая заключена в CATCH блоке.
https://msdn.microsoft.com/en-us/library/ms175976.aspx
Так поведение TRY-CATCH скорее напротив вашего намерения.
GO
устанавливает окончание партии. Многие из ошибок даже не разбивают пакет, потому что у них есть low severity, поэтому для некоторых случаев нет необходимости даже разбить скрипт на многие партии.
В качестве примера здесь приведен пример фиктивной сценария для тестирования или какого-бытового назначения (не для производства, конечно), что порождает множество ошибок:
create proc SomeProc as
begin
exec('select uknown from non_existent')
end
GO
drop table #test1
drop table #test2
GO
drop table #test3
GO
create table #test1 (id int primary key)
insert into #test1(id)
exec SomeProc
insert into #test
values (1)
insert into #test1
values (1)
GO
insert into #test1
values (11)
insert into #test1
values (11)
insert into #test
values (22)
GO
select * from #test1
GO
drop table #test
GO
drop table #test
drop proc SomeProc
select object_id('SomeProc', 'P')
GO
он дает выход выбирает:
и все сообщения:
Msg 3701, Level 11, St ate 5, Line 7 Невозможно удалить таблицу «# test2», , потому что она не существует или у вас нет разрешения.
Msg 3701, Level 11, State 5, Line 9 Невозможно отказаться от таблицы '# test3', потому что у нее не существует или у вас нет разрешения.
Msg 208, Level 16, State 1, Строка 11 Недопустимое имя объекта 'non_existent'.
(0 строк (ы) пострадавших)
Msg 208, уровень 16, состояние 0, строка 16 Недопустимый объект имя '#test'.
(1 ряд (ы) пострадавшие)
Сообщи 2627, Уровень 14, состояние 1, строка 25 Нарушение первичного ключ 'ПК __ # test1____3213E83FF35979C1'. Невозможно вставить дублирующий ключ в объекте 'dbo. # Test1'. Значение дублирующегося ключа равно (11). Заявление было прекращено.
Msg 208, Level 16, State 0, Line 28 Неверное имя объекта '#test'.
(1 строка (s) пострадавших)
Msg 3701, Level 11, Состояние 5, строка 33 Невозможно удалить таблицу '#test', потому что он не существует, или у вас нет разрешения.
Msg 3701, уровень 11, состояние 5, строка 35 Невозможно отказаться от таблицы '#test', потому что она не существует или у вас нет разрешения.
«Моя цель - уловить сообщение об ошибке из SQL-запроса, журнала или печати, а затем передать его вместо того, чтобы позволить ему генерировать реальную ошибку». - если «печать» в порядке, то просто удалите TRY-CATCH
.
На самом деле, я думаю, что это ловит * первый * ошибка не последний. Если вы не восстановите ошибку, двигатель не сможет продолжить обработку. –
@ GordonLinoff верен. Как только первая ошибка будет брошена, двигатель не будет обрабатываться дальше. Поэтому вам не нужно беспокоиться о том, чтобы поймать несколько ошибок. – Sam
@ GordonLinoff. Да, если есть несколько запросов, он остановится при первом запросе; но моя вещь - это один запрос, генерирующий несколько ошибок (как и мой пример, создание схемы или использование SP или EXEC (@query), что содержащий запрос выбирает сразу два недопустимых столбца). – a4194304