Проблемы с T-SQL TRY CATCH?

В настоящее время мы работаем над SQL 2005, и я переношу старую систему Foxpro в новое веб-приложение под SQL Server. Я использую TRY CATCH в T-SQL для обработки транзакций и, похоже, работает очень хорошо. Один из других программистов на работе беспокоился об этом, поскольку он сказал, что слышал о проблемах, когда фраза catch не всегда ломала ошибку. Я избил sproc до смерти и не могу заставить его потерпеть неудачу (пропустить улов), и единственные проблемы, которые я обнаружил в сети, это то, что он не вернет правильный номер ошибки для номеров ошибок < 5000. Кто-нибудь испытал какие-либо другие проблемы с TRY CATCH в T-SQL - особенно, если он упустил улов? Спасибо за любой вклад, который вы можете пожелать предоставить.

Ответ 1

TRY ... CATCH не улавливает все возможные ошибки, но те, которые не пойманы, хорошо документированы в BOL Ошибки, не затронутые TRY... CATCH Construct

TRY... Конструкции CATCH не захватывают следующие условия:

  • Предупреждения или информационные сообщения с серьезностью 10 или ниже.
  • Ошибки с серьезностью 20 или выше, которые останавливают SQL Server Обработка задачи Database Engine для сессия. Если возникает ошибка, имеет степень тяжести 20 или выше, а соединение с базой данных не прерывается, TRY... CATCH будет обрабатывать ошибку.
  • Внимания, такие как запросы прерывания клиента или сломанные клиентских подключений.
  • Когда сеанс завершается системным администратором, используя KILL выражение.

Следующие типы ошибок не обрабатывается блоком CATCH, когда они происходят на одном уровне исполнения как конструкция TRY... CATCH:

  • Скомпилировать ошибки, такие как синтаксические ошибки, препятствующие пакету работает.
  • Ошибки, возникающие при перекомпиляции на уровне инструкций, например ошибки разрешения имен объектов, которые происходят после компиляции из-за отложенное разрешение имен.

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

Ответ 2

В моем опыте был один случай, когда TRY... Блок CATCH не поймал ошибку. При сопоставлении произошла ошибка: Не удается разрешить конфликт сопоставления между "Latin1_General_CI_AS" и "Latin1_General_CI_AI" в равном действию. Возможно, эта ошибка соответствует одному из типов ошибок, задокументированных в BOL.

Ошибки, возникающие при перекомпиляции на уровне инструкций, такие как объект ошибки разрешения имен, возникающие после компиляции из-за разрешение отложенного имени.

Ответ 3

TRY ... CATCH не сможет поймать ошибку, если вы пройдете "плохой" поисковый запрос до CONTAINSTABLE

Например:

DECLARE @WordList VARCHAR(800)
SET @WordList = 'crap"s'
CON

TAINSTABLE(table, *, @WordList)

CONTAINSTABLE даст вам "синтаксическую ошибку", и все окружающие TRY ... CATCH не поймут это.

Это особенно неприятно, потому что ошибка вызвана данными, а не "реальной" синтаксической ошибкой в ​​вашем коде.

Ответ 4

Я работаю в SQL Server 2008. Я построил большой sql-оператор с try/catch. Я протестировал его, переименовав таблицу (в dev). Заявление взорвалось и не уловило ошибку. Try/catch в SQL Server слаб, но лучше, чем ничего. Вот часть моего кода. Я не могу больше вкладывать из-за ограничений моей компании.

    COMMIT TRAN T1;
END TRY
BEGIN CATCH
    -- Save the error.
    SET @ErrorNumber = ERROR_NUMBER();
    SET @ErrorMessage = ERROR_MESSAGE();
    SET @ErrorLine = ERROR_LINE();
    -- Put GSR.dbo.BlahBlahTable back the way it was.
    ROLLBACK TRAN T1;   
END CATCH
-- Output a possible error message. Knowing what line the error happened at really helps with debugging.
SELECT @ErrorNumber as ErrorNumber,@ErrorMessage as ErrorMessage,@ErrorLine AS LineNumber;

Ответ 5

Я никогда не сталкивался с ситуацией, когда TRY... CATCH... не удалось. Возможно, у Neiteher было много людей, которые прочитали этот вопрос. Это, увы, означает только, что если есть такая ошибка SQL, то мы ее не видели. Дело в том, что довольно большое "если". Верьте или нет, Microsoft прилагает определенные усилия, чтобы сделать их основные программные продукты довольно прочными, а TRY... CATCH... вряд ли является новой концепцией. Быстрый пример: в SQL 2005 я столкнулся с твердой, очевидной и реплицируемой ошибкой при разработке тогдашнего нового разбиения таблиц - эта ошибка, которая уже была исправлена ​​патчем. И TRY... CATCH... используется немного чаще, чем разбиение таблиц.

Я бы сказал, что бремя доказывания ложится на вашего коллегу. Если он "где-то слышал", то он должен попытаться поддержать его с помощью каких-то доказательств. Интернет полна доказательств для старой поговорки "только потому, что все говорят так, не означает, что они правы".