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 може бути дуже гордий за тебе!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ