Как в SQL Server повторно вызвать исключение: практика
Быстрый ответ
Для повторного возбуждения исключения в SQL Server с помощью команды THROW
, воспользуйтесь следующим примером кода:
BEGIN TRY
-- Код, содержащий операций, способные вызвать ошибку
END TRY
BEGIN CATCH
THROW; -- Воспроизведение исключения с сохранением всех деталей
END CATCH
Такой подход сохраняет всю информацию об исходной ошибке просто и изящно.
THROW против RAISERROR: Бурные дебаты
В области обработки исключений SQL Server ключевое слово THROW
появилось сравнительно недавно — с внедрением SQL Server 2012. Его главное преимущество в том, что THROW
позволяет воспроизвести исходные исключения, сохранив их контекст, сообщение, уровень критичности и состояние. В то время как RAISERROR
может потребовать явной передачи этих параметров. В таком случае существует риск потери исходного контекста ошибки.
Управление транзакциями как профессионал
Компетентное управление транзакциями внутри блока TRY...CATCH критично, особенно когда речь идёт об исполнении связанных операций, которые должны быть либо все успешно выполнены, либо все откачены в случае ошибки:
BEGIN TRY
BEGIN TRANSACTION;
-- Выполнение операций с базой данных
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION; -- Если во время транзакции произошла ошибка, отменяем все изменения
THROW; -- Воспроизводим исключение
END CATCH
Проверка значения @@TRANCOUNT
позволяет определить наличие незавершенных транзакций перед их подтверждением или отменой.
Извлечение сведений об ошибках для новичков
Чтобы получить информацию об ошибке в блоке CATCH
, используйте ERROR_MESSAGE()
, ERROR_NUMBER()
и ERROR_PROCEDURE()
:
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage,
ISNULL(ERROR_PROCEDURE(), '-') AS ErrorProcedure;
THROW; -- Исключение возбуждается повторно с сохранением контекста
END CATCH
Контроль над ошибками SQL Server
Стоит обеспечить, чтобы пользовательские ошибки не смешивались с системными. Все ошибки, определенные пользователем, должны иметь номер выше 50000, чтобы избежать путаницы с системными сообщениями.
Предыдущие версии SQL Server? Нет проблем
Если вы работаете с версией SQL Server ранее 2012 года, не беспокойтесь, существует решение, имитирующее поведение THROW
с помощью RAISERROR
:
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorNumber INT;
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorNumber = ERROR_NUMBER(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
-- Возвращаем ошибку с полной информацией о ней
END CATCH
Это может показаться немного многословным, но такова реалия работы с устаревшими версиями SQL.
Визуализация
Представим процесс повторного вызова исключения в SQL как бумеранг:
1. SQL Server генерирует ошибку: ☠️
2. Ошибка попадает в блок CATCH: 🤲
3. Активируется RETHROW: 🔄
4. Ошибка возвращается обратно в обработку SQL: 🪃
Попробуй {
// Код, который может вызвать ошибку ☠️
} Поймай {
// Ошибка попадает в обработчик Catch 🤲
RETHROW; // И исключение снова в пути 🪃
}
Исключение возвращается к источнику, сохраняя стартовый контекст.
Ожидание будущих улучшений в SQL Server
Следите за возможными улучшениями в области обработки ошибок, поскольку SQL Server продолжает совершенствоваться. Ожидается более глубокий контроль над исключениями и улучшение интеграции с фронтенд-технологиями. Подготовьтесь к созданию более надёжных и стабильных приложений!
Полезные материалы
- THROW (Transact-SQL) – SQL Server | Microsoft Learn — Официальная документация по
THROW
в Transact-SQL. - TRY...CATCH (Transact-SQL) – SQL Server | Microsoft Learn — Руководство по обработке ошибок для начинающих с использованием
TRY...CATCH
. - sql – What is the syntax meaning of RAISERROR() – Stack Overflow — Обсуждение
THROW
противRAISERROR
. - Handling Errors in SQL Server 2012 – Simple Talk — Обсуждение обработки ошибок в SQL Server 2012, не такое уж простое, как кажется.
- SQL Server 2005 Log File Viewer — Руководство по использованию просмотрщика логов SQL Server для устранения непредсказуемых неполадок.