Остановка исполнения SQL-скрипта на SQL Server: условный выход

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

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

Если необходимо прервать выполнение скрипта на SQL Server, можно обратиться к конструкции RAISERROR('Текст ошибки', 11, 1) и применить к ней оператор RETURN. Пример выглядит следующим образом:

SQL
Скопировать код
-- Начинаем выполнение...
SELECT 'Поехали!';

-- Прерываем выполнение
RAISERROR('Выполнение остановлено.', 11, 1);
RETURN;

-- Этот блок не будет выполнен
SELECT 'Этот код уже не выполнится.';

Учтите, что RAISERROR прервёт выполнение только в пределах текущего блока, поэтому тщательно планируйте структуру вашего скрипта.

Простые и эффективные способы приостановить выполнение

Если ваша задача – контролировать выполнение SQL-скрипта, представлены различные способы установки "стоп-сигнала" в нужный момент.

Использование "set noexec on/off" для "мягкой" остановки

Чтобы "мягко" приостановить выполнение скрипта, используйте set noexec on. Снять блокировку и продолжить исполнение можно с помощью set noexec off:

SQL
Скопировать код
-- Начинаем
PRINT 'Где ты, Ромео?';

-- Останавливаем
SET NOEXEC ON;

-- Этот блок будет пропущен
INSERT INTO LoveStory VALUES('Ромео', 'Джульетта');

-- Возобновляем выполнение
SET NOEXEC OFF;

Элегантный выход с "RETURN"

Оператор RETURN позволяет изящно прекратить выполнение скрипта, без возникновения ошибок:

SQL
Скопировать код
IF @@ROWCOUNT = 0
BEGIN
    PRINT 'Строк нет. Отменяю действия...';
    RETURN;
END

Использование локальных переменных для контроля выполнения

Через IF и переменные можно управлять ходом выполнения и внедрить нужную логику:

SQL
Скопировать код
DECLARE @is_valid BIT = 1; -- Запускаем

-- Проверяем условие
IF EXISTS(SELECT * FROM Drama WHERE Twist = 'Недопустим')
    SET @is_valid = 0;

-- Если условие не выполняется, завершаем
IF @is_valid = 0
    RETURN;

"TRY...CATCH" для управления исключениями

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

SQL
Скопировать код
BEGIN TRY
   -- Проблемное действие
   INSERT INTO Protagonists(ID, Name) VALUES(1, 'Главный герой');
END TRY
BEGIN CATCH
   -- Обработка ошибки
   THROW;
END CATCH

Использование "IF NOT EXISTS" для предотвращения дублирования данных

Употребляйте IF NOT EXISTS, чтобы избежать добавления дублирующих данных:

SQL
Скопировать код
IF NOT EXISTS(SELECT * FROM Protagonists WHERE ID=1)
    INSERT INTO Protagonists(ID, Name) VALUES(1, 'Главный герой');
ELSE
    RAISERROR('Главный герой уже есть, повторное добавление невозможно.', 16, 1);

Визуализация

Логику работы SQL-скрипта можно ассоциировать с поездкой на поезде:

Markdown
Скопировать код
🚂 Поездка: [| Старт |-->| Всё в порядке 🟢 |-->| Продолжаем |-->| Стоп 🛤️ |]
             [| Старт |-->| Произошла ошибка 🔴 |-->| Экстренное торможение: RAISERROR |]

Зелёный сигнал – выполнение без ошибок (BEGIN TRY), красный – серьёзная ошибка (BEGIN CATCH + RAISERROR).

Markdown
Скопировать код
BEGIN TRY
    -- Код без ошибок
END TRY
Markdown
Скопировать код
BEGIN CATCH
    -- Ошибка!
    RAISERROR('Произошла ошибка.', 16, 1)
END CATCH

Управление потоком и обработка ошибок: на пути к мастерству

Развитие умений в обработке ошибок и управлении потоком данных предполагает применение расширенных методов.

Работа с "SQLCMD mode"

Используйте режим sqlcmd.exe и директиву :on error exit для детального контроля над скриптом:

SQL
Скопировать код
:on error exit
GO

SELECT * FROM TableOfDoom; -- Серьёзная ошибка. Скрипт останавливается.

Контроль сложных процессов с помощью флагов

Для эффективного контроля над скриптами необходимо задействовать структурированные флаги:

SQL
Скопировать код
DECLARE @ControlFlags TABLE(FlagKey VARCHAR(100), FlagValue INT);
INSERT INTO @ControlFlags VALUES('IsValid', 1);

-- Усложняем сюжет
IF EXISTS(...) UPDATE @ControlFlags SET FlagValue = 0 WHERE FlagKey = 'IsValid';

-- Проверяем состояние перед концовкой
IF (SELECT FlagValue FROM @ControlFlags WHERE FlagKey = 'IsValid') = 0
    THROW 50001, 'Герой пал, действие закончено.', 1;

Использование 'RAISERROR' без прав администратора

Если нет административных прав, но нужно контролировать выполнение:

SQL
Скопировать код
BEGIN TRY
    -- Рискованное действие
    SELECT 1/0; -- Ошибочная операция
END TRY
BEGIN CATCH
    PRINT 'Операция не удалась, прерываем.';
    SET NOEXEC ON;
END CATCH

Разбиение скрипта на блоки с помощью 'GO'

Команда GO помогает разбивать скрипт на независимые блоки:

SQL
Скопировать код
-- Часть 1
SELECT 'Прекрасная Верона, здесь начинает развиваться наше действие.';

-- Ошибка прервет только следующие блоки
GO
RAISERROR('Проклятие на оба ваши дома!', 16, 1);

GO
-- Часть 2 не будет выполнена
SELECT 'Все виноваты.';

Применение 'THROW' для взаимодействия с пользователями

THROW помогает формировать индивидуальные сообщения об ошибках:

SQL
Скопировать код
-- Проверяем условие
IF NOT EXISTS(SELECT * FROM Audience WHERE Bored>'Extremely')
    THROW 50002, 'Внимание! Мы потеряли зрителей.', 1;

Использование 'PRINT' для прояснения процесса

С помощью команды PRINT можно добавить комментарии для более чёткого понимания происходящего:

SQL
Скопировать код
-- Подготовка зрителей к развязке
PRINT 'Распутываем тайну фантома...';

-- Ответ
PRINT 'Фантом – это дворецкий!';

Рекомендации MSDN

Microsoft Developer Network (MSDN) предоставляет большой объём знаний по SQL, включая детали использования THROW, который по умолчанию генерирует ошибку уровня 16, и другую ценную информацию.

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

  1. Transact-SQL (Движок базы данных) – SQL Server | Microsoft Learn
  2. Как прекратить выполнение скрипта в SQL Server?
  3. Использование транзакций и точек сохранения в SQL Server
  4. Возможности RAISERROR в SQL Server