Уяви, ти пишеш функцію, яка рахує середній бал студента. Що буде, якщо спробуєш поділити на нуль (наприклад, якщо оцінки відсутні)? Випустиш такий код у прод — і несподіваний гість у вигляді помилки одразу з’явиться. PL/pgSQL дає круті інструменти для обробки таких помилок, роблячи твій код стійким, безпечним і кайфовим для роботи.
Обробка помилок у PL/pgSQL дозволяє:
- Генерувати повідомлення, які пояснюють, що пішло не так.
- Зупиняти виконання коду у випадку критичних фейлів.
- Логувати трабли для подальшого аналізу.
Основні рівні повідомлень 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 може зупиняти виконання важливих операцій. Використовуй його з розумом.
Корисні поради
- Будь уважний з блоком
WHEN OTHERS. По можливості вказуй конкретні помилки, щоб не перехопити ті, які треба обробити інакше. - Використовуй
RAISEдля дебагу. Ніколи не залишай помилки необробленими. - Не забувай про продуктивність. Обробка помилок може бути затратною, особливо у великих процедурах.
Якщо ти все зробиш правильно, твої процедури стануть стійкими і зможуть пережити навіть неочікувані фейли. PM може бути дуже гордий за тебе!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ