@@ERROR и/или TRY - CATCH
Будет ли Try-Catch фиксировать все ошибки, которые могут возникнуть при @@ERROR? В следующем фрагменте кода стоит проверить на @@ERROR? Возникнет ли RETURN 1111?
SET XACT_ABORT ON
BEGIN TRANSACTION
BEGIN TRY
--do sql command here <<<<<<<<<<<
SELECT @[email protected]@ERROR
IF @Error!=0
BEGIN
IF XACT_STATE()!=0
BEGIN
ROLLBACK TRANSACTION
END
RETURN 1111
END
END TRY
BEGIN CATCH
IF XACT_STATE()!=0
BEGIN
ROLLBACK TRANSACTION
END
RETURN 2222
END CATCH
IF XACT_STATE()=1
BEGIN
COMMIT
END
RETURN 0
Ответы
Ответ 1
Следующая статья является обязательной для прочтения Erland Sommarskog, SQL Server MVP: реализация обработки ошибок с помощью хранимых процедур
Также обратите внимание, что ваш блок TRY может не работать, и ваш блок CATCH может быть обойден
Еще одна вещь: хранимые процедуры, использующие обработку ошибок старого стиля и точки сохранения, могут работать не так, как предполагалось, когда они используются вместе с блоками TRY… CATCH. Избегайте смешивания старых и новых стилей обработки ошибок.
Ответ 2
TRY/CATCH ловушки больше. Это невероятно и удивительно лучше.
DECLARE @foo int
SET @foo = 'bob' --batch aborting pre-SQL 2005
SELECT @@ERROR
GO
SELECT @@ERROR --detects 245. But not much use, really if the batch was a stored proc
GO
DECLARE @foo int
BEGIN TRY
SET @foo = 'bob'
SELECT @@ERROR
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE(), ERROR_NUMBER()
END CATCH
GO
Использование TRY/CATCH в триггерах также работает. Сброс триггера также используется для прерывания партии: больше нет, если TRY/CATCH также используется в триггере.
Ваш пример был бы лучше, если BEGIN/ROLLBACK/COMMIT находится внутри, а не снаружи, конструкцию
Ответ 3
Try Catch не будет ловить все
вот какой код, чтобы продемонстрировать, что
BEGIN TRY
BEGIN TRANSACTION TranA
DECLARE @cond INT;
SET @cond = 'A';
END TRY
BEGIN CATCH
PRINT 'a'
END CATCH;
COMMIT TRAN TranA
Сервер: Msg 3930, уровень 16, состояние 1, строка 9
Текущая транзакция не может быть зафиксирована и не может поддерживать операции, которые записываются в файл журнала. Отмените транзакцию.
Сервер: Msg 3998, уровень 16, состояние 1, строка 1
Неопределенная транзакция обнаружена в конце пакета. Сделка отменяется.
Ответ 4
Я не верю, что управление когда-либо достигнет инструкции RETURN - как только вы попадете в блок TRY, любая ошибка будет передана в блок CATCH. Тем не менее, есть некоторые очень серьезные ошибки, которые могут привести к остановке партии или даже самого соединения (Erland Sommarskog написал на тему ошибок в SQL Server здесь и здесь - к сожалению, он не обновил их, включив TRY... CATCH). Я не уверен, что вы можете использовать такую ошибку, но тогда @@ERROR тоже не годится.
Ответ 5
По моему опыту, в соответствии с книгой Online, TRY... Блоки CATCH будут захватывать все события, которые будут генерировать ошибки (и, таким образом, установить @@ERROR на ненулевое значение). Я не могу придумать никаких обстоятельств, когда это не применимо. Таким образом, нет, возвращаемое значение никогда не будет установлено в 1111, и не стоит включать эту ошибку @@Error.
Однако обработка ошибок может быть очень важна, и я буду хеджировать свои ставки для таких ситуаций, как DTC, связанные серверы, службы уведомлений или брокерских услуг и другие функции SQL, с которыми у меня было очень мало опыта. Если вы можете, проверьте свои более странные ситуации, чтобы увидеть, что на самом деле произойдет.
Ответ 6
Весь смысл "Try..Catch" заключается в том, что вам не нужно проверять наличие @@ERROR для каждого утверждения.
Так что это не стоит.