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

#sql-server #tsql #try-catch

#sql-server #tsql #попробуйте-catch

Вопрос:

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

Комментарии:

1. Многих смущает то, что предложение CATCH не будет введено, если произойдет ошибка компиляции, например, отсутствует столбец / таблица.

Ответ №1:

TRY ... CATCH не улавливает все возможные ошибки, но те, которые не улавливаются, хорошо документированы в BOL Ошибки, на которые не влияет конструкция TRY … CATCH

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

  • Предупреждения или информационные сообщения, степень серьезности которых равна 10 или ниже.
  • Ошибки, серьезность которых равна 20 или выше, которые останавливают обработку задачи SQL Server Database Engine для сеанса. Если возникает ошибка серьезностью 20 или выше, а подключение к базе данных не нарушено, ПОПРОБУЙТЕ … 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…ПОЙМАТЬ … не удалось. Также, вероятно, есть много людей, которые читают этот вопрос. Это, увы, означает только то, что если такая ошибка SQL существует, то мы ее не видели. Дело в том, что это довольно большое «если». Хотите верьте, хотите нет, но Microsoft прилагает определенные усилия, чтобы сделать свои основные программные продукты довольно надежными, и ПЫТАЕТСЯ…CATCH … вряд ли является новой концепцией. Краткий пример: В SQL 2005 я столкнулся с серьезной, очевидной и воспроизводимой ошибкой при разработке нового разбиения таблицы на разделы — ошибка, которая уже была исправлена патчем. И ПОПРОБУЙТЕ…CATCH … используется немного чаще, чем разбиение таблицы.

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

Комментарии:

1. Я задал общий вопрос, не возникало ли у кого-нибудь каких-либо проблем с TRY CATCH — я никого не просил что-либо доказывать.

2. -1, T-SQL Try Catch не обрабатывает ошибки интеграции CLR. Тем не менее, вопрос был полезным, а другой ответ информативным.