JavaRush /Курсы /SQL SELF /Обработка ошибок: RAISE EXCEPTION

Обработка ошибок: RAISE EXCEPTION

SQL SELF
52 уровень , 0 лекция
Открыта

Представьте, вы пишете функцию, которая считает средний балл студента. Что произойдет, если попытаетесь разделить на ноль (например, если оценки отсутствуют)? Попробуете выпустить в реальную жизнь такой код — и нежданный гость в лице ошибки тут же заявится. PL/pgSQL предоставляет мощные инструменты для обработки таких ошибок, делая ваш код устойчивым, безопасным и приятным для работы.

Обработка ошибок в PL/pgSQL позволяет:

  1. Генерировать сообщения, объясняющие, что пошло не так.
  2. Прекращать выполнение кода в случае критических ошибок.
  3. Логировать проблемы для последующего анализа.

Основные уровни сообщений PL/pgSQL

PL/pgSQL поддерживает несколько уровней сообщений, которые помогают разработчикам эффективно диагностировать и устранять проблемы. Вот они:

  • NOTICE: выводит информационное сообщение. Применяется для отладки.
  • WARNING: уведомление о потенциальной проблеме, которая не прерывает выполнение программы.
  • EXCEPTION: критическая ошибка, прерывающая выполнение программы (и возвращающая управление вызывающему коду).

Уровни сообщений в PL/pgSQL

Уровень сообщения Описание
NOTICE Информация или отладочные сообщения. Не влияет на выполнение
WARNING Предупреждение о возможных проблемах. Работает как подсказка
EXCEPTION Серьезная ошибка, которая завершает выполнение программы

Синтаксис команды RAISE

Для генерации сообщений и обработки ошибок используется оператор RAISE. Вот его базовый синтаксис:

RAISE <уровень сообщения> 'текст сообщения' [, переменные...];
  • <уровень сообщения>NOTICE, WARNING, EXCEPTION.
  • 'текст сообщения' — описание проблемы.
  • [переменные...] — дополнительные значения, которые можно передать в текст сообщения.

Пример 1: использование RAISE NOTICE

Иногда важно знать, что происходит внутри вашей функции. Скажем, для отладки цикла:

DO $$
BEGIN
    FOR i IN 1..5 LOOP
        RAISE NOTICE 'Текущее значение i: %', i;
    END LOOP;
END
$$;

Результат: Вывод в консоль строк Текущее значение i: 1, Текущее значение i: 2 и так далее до 5.

Пример 2: использование RAISE EXCEPTION

Теперь представим, вы пишете функцию, которая должна завершаться с ошибкой при определённых условиях:

DO $$
BEGIN
    IF 1 = 1 THEN
        RAISE EXCEPTION 'Что-то пошло не так!';
    END IF;
END
$$;

Результат: выполнение прерывается, и сообщение ошибки выводится в консоль.

Работа с параметрами в RAISE

Используя параметры, вы можете персонализировать текст сообщения. Для этого применяются плейсхолдеры %:

Пример 3: вставка переменных в RAISE

DO $$
DECLARE
    student_name TEXT := 'Иван';
    average_score NUMERIC := NULL;
BEGIN
    IF average_score IS NULL THEN
        RAISE EXCEPTION 'У студента % нет среднего балла!', student_name;
    END IF;
END
$$;

Результат: сообщение У студента Иван нет среднего балла!.

Как видите, % заменяется на переменную student_name, что делает сообщение более осмысленным.

Генерация пользовательских ошибок

Ошибки — это не только форс-мажор! Иногда их нужно создавать намеренно, чтобы защитить код от неправильных данных.

Пример 4: проверка входных значений

Напишем функцию, которая проверяет входное значение числа и вызывает ошибку, если оно отрицательное:

CREATE OR REPLACE FUNCTION check_positive(value NUMERIC)
RETURNS TEXT AS $$
BEGIN
    IF value < 0 THEN
        RAISE EXCEPTION 'Число % является отрицательным!', value;
    END IF;
    RETURN 'Число корректно.';
END;
$$ LANGUAGE plpgsql;

Теперь протестируем функцию:

SELECT check_positive(-5);

Результат: сообщение об ошибке Число -5 является отрицательным!.

Если же передать положительное значение:

SELECT check_positive(10);

Результат: Число корректно.

Обработка ошибок в контексте

Хорошо, если вы умеете генерировать ошибки. Но ещё лучше — обрабатывать их в зависимости от ситуации. Для этого используется блок BEGIN ... EXCEPTION.

Структура обработки ошибок

BEGIN
    -- Ваш основной код
EXCEPTION
    WHEN ОШИБКА_ТИП THEN
        -- Что делать в случае ошибки
    WHEN ДРУГАЯ_ОШИБКА THEN
        -- Действия при другой ошибке
    WHEN OTHERS THEN
        -- Обработка всех остальных ошибок
END;

Расшифруем компоненты:

  • EXCEPTION — ключевое слово, обозначающее начало блока обработки ошибок.
  • WHEN — позволяет указать конкретный тип обрабатываемой ошибки, например, unique_violation или division_by_zero.
  • OTHERS — используется для обработки всех ошибок, которые не были явно указаны в блоках WHEN.

Пример 5: обработка деления на ноль

Проиллюстрируем обработку ошибки с простым примером функции деления:

CREATE OR REPLACE FUNCTION safe_divide(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    -- Пытаемся выполнить деление
    RETURN a / b;
EXCEPTION
    WHEN division_by_zero THEN
        RAISE WARNING 'Попытка деления на ноль. Возвращаю NULL.';
        RETURN NULL;
END;
$$ LANGUAGE plpgsql;

Протестируем функцию:

SELECT safe_divide(10, 2);  -- Ожидаемый результат: 5
SELECT safe_divide(10, 0);  -- Ожидаемый результат: NULL и предупреждение в консоли

Типичные ошибки при использовании RAISE

Пропуск уровня сообщения. Если вы забыли указать уровень, PostgreSQL выдаст ошибку.

Неправильно:

RAISE 'Сообщение без уровня';

Правильно:

RAISE NOTICE 'Сообщение с уровнем NOTICE';

Неверные параметры. Если используете %, убедитесь, что передаёте необходимое количество переменных.

Неправильно:

RAISE NOTICE 'Пример с параметром %';

Правильно:

RAISE NOTICE 'Пример с параметром %', 'значение';

Перебивание. Чрезмерное использование RAISE EXCEPTION может прерывать выполнение важных операций. Используйте его разумно.

Полезные советы

  1. Будьте внимательны с блоком WHEN OTHERS. По возможности указывайте конкретные ошибки, чтобы избежать перехвата ошибок, которые должны быть обработаны по-другому.
  2. Используйте RAISE для отладки. Никогда не оставляйте ошибки необработанными.
  3. Не забывайте про производительность. Обработка ошибок может быть затратной, особенно в больших процедурах.

Если вы все сделаете правильно, то ваши процедуры станут устойчивыми и смогут выдержать даже неожиданные сбои. PM может быть очень горд за вас!

2
Задача
SQL SELF, 52 уровень, 0 лекция
Недоступна
Обработка деления на ноль
Обработка деления на ноль
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ