#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. Тем не менее, вопрос был полезным, а другой ответ информативным.