Как в SQL Server повторно вызвать исключение: практика

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для повторного возбуждения исключения в SQL Server с помощью команды THROW, воспользуйтесь следующим примером кода:

SQL
Скопировать код
BEGIN TRY
    -- Код, содержащий операций, способные вызвать ошибку
END TRY
BEGIN CATCH
    THROW; -- Воспроизведение исключения с сохранением всех деталей
END CATCH

Такой подход сохраняет всю информацию об исходной ошибке просто и изящно.

Кинга Идем в IT: пошаговый план для смены профессии

THROW против RAISERROR: Бурные дебаты

В области обработки исключений SQL Server ключевое слово THROW появилось сравнительно недавно — с внедрением SQL Server 2012. Его главное преимущество в том, что THROW позволяет воспроизвести исходные исключения, сохранив их контекст, сообщение, уровень критичности и состояние. В то время как RAISERROR может потребовать явной передачи этих параметров. В таком случае существует риск потери исходного контекста ошибки.

Управление транзакциями как профессионал

Компетентное управление транзакциями внутри блока TRY...CATCH критично, особенно когда речь идёт об исполнении связанных операций, которые должны быть либо все успешно выполнены, либо все откачены в случае ошибки:

SQL
Скопировать код
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():

SQL
Скопировать код
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:

SQL
Скопировать код
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 как бумеранг:

Markdown
Скопировать код
1. SQL Server генерирует ошибку: ☠️
2. Ошибка попадает в блок CATCH: 🤲
3. Активируется RETHROW: 🔄
4. Ошибка возвращается обратно в обработку SQL: 🪃
Markdown
Скопировать код
Попробуй {
   // Код, который может вызвать ошибку ☠️
} Поймай {
   // Ошибка попадает в обработчик Catch 🤲
   RETHROW; // И исключение снова в пути 🪃
}

Исключение возвращается к источнику, сохраняя стартовый контекст.

Ожидание будущих улучшений в SQL Server

Следите за возможными улучшениями в области обработки ошибок, поскольку SQL Server продолжает совершенствоваться. Ожидается более глубокий контроль над исключениями и улучшение интеграции с фронтенд-технологиями. Подготовьтесь к созданию более надёжных и стабильных приложений!

Полезные материалы

  1. THROW (Transact-SQL) – SQL Server | Microsoft LearnОфициальная документация по THROW в Transact-SQL.
  2. TRY...CATCH (Transact-SQL) – SQL Server | Microsoft LearnРуководство по обработке ошибок для начинающих с использованием TRY...CATCH.
  3. sql – What is the syntax meaning of RAISERROR() – Stack Overflow — Обсуждение THROW против RAISERROR.
  4. Handling Errors in SQL Server 2012 – Simple Talk — Обсуждение обработки ошибок в SQL Server 2012, не такое уж простое, как кажется.
  5. SQL Server 2005 Log File Viewer — Руководство по использованию просмотрщика логов SQL Server для устранения непредсказуемых неполадок.