Не удается получить @@ERROR после EXEC() с ошибкой

См. следующий код t-sql

DECLARE @iError INT
 EXEC('select * from sysobj')
 SELECT @iError = @@ERROR
 PRINT 'Error = ' + CAST(@iError AS VARCHAR(10))

После запуска, он возвращает сообщение об ошибке, которое я хочу.

Msg 208, уровень 16, состояние 1, строка 1 Недопустимое имя объекта 'sysobj'. Ошибка = 208

Однако, если я изменяю запрос

DECLARE @iError INT
 EXEC('select * from sysobjects where ''c'' = 1')
 SELECT @iError = @@ERROR
 PRINT 'Error = ' + CAST(@iError AS VARCHAR(10))

Выход будет

Msg 245, уровень 16, состояние 1, строка 1 Ошибка конверсии при преобразовании значения var car в тип данных int.

Проблема в том, что любой код afer EXEC() не выполняется.

В реальной хранимой процедуре у меня есть код для обработки ошибок после PRINT. И ни один из этих кодов не выполняется во втором случае.

Может ли кто-нибудь сообщить мне, почему это происходит?

Я тестировал его как на SQL Server 2008, так и на 2005 год.

Спасибо

3 ответа

Различные ошибки будут иметь разные уровни прерывания, а некоторые из них можно контролировать с помощью настроек, таких как ARITHIGNORE и ANSI_WARNINGS.

Я предлагаю прочитать следующую статью, которая подробно объясняет все это.

http://www.sommarskog.se/error-handling-I.html#whathappens

Заявление о прекращении и пакетном аборте

Эти две группы содержат регулярные ошибки во время выполнения, такие как дубликаты в уникальных индексы, нехватка дискового пространства и т.д. Как я уже говорил, ошибка, которая вызывает, что действие не всегда легко предсказать заранее. Эта в таблице перечислены некоторые распространенные ошибки и отменяются ли они или весь пакет.


Здесь есть статья об msdn здесь. Он имеет отношение к контексту, в котором выполняется оператор EXEC(). Если вы включили ошибку в параметр, переданный в EXEC(), вы можете записать его в таблицу temp, а затем посмотреть на это.

Вот их пример:

DECLARE @cmd VARCHAR(1000), @ExecError INT
CREATE TABLE #ErrFile (ExecError INT)
SET @cmd = 'EXEC GetTableCount ' + 
'''pubs.dbo.authors''' + 
'INSERT #ErrFile VALUES(@@ERROR)'
EXEC(@cmd)
SET @ExecError = (SELECT * FROM #ErrFile)
SELECT @ExecError AS '@@ERROR'


Посмотрите на реализацию TRY... CATCH для обработки ошибок. Затем вы можете поместить всю свою обработку ошибок в блок CATCH.

licensed under cc by-sa 3.0 with attribution.