PL/SQL - Исключения: Пособие для начинающих

Здравствуйте, будущие мастера PL/SQL! Сегодня мы окунемся в fascинирующий мир исключений в PL/SQL. Не волнуйтесь, если вы новички в программировании - я проведу вас по этой теме шаг за шагом, как я делал это для countless студентов на протяжении многих лет моего преподавания. Так что возьмите杯 кофе (или чай, если это ваше дело) и отправляйтесь в это захватывающее путешествие вместе со мной!

PL/SQL - Exceptions

Что такое исключения?

Прежде чем мы углубимся в Details, давайте поймем, что такое исключения. Представьте, что вы печете торт (присоединяйтесь ко мне, я обещаю, это связано с программированием). Вы следуете рецепту шаг за шагом, но вдруг понимаете, что у вас закончились яйца! Эта неожиданная ситуация аналогична исключению в программировании.

В PL/SQL исключения - это неожиданные события, которые нарушают нормальный ход вашей программы. Они могут быть ошибками, такими как попытка разделить на ноль или попытка вставить дублиручное значение в уникальный столбец. Вместо того чтобы позволить этим проблемам обрушить нашу программу, мы можем "обработать" их优雅но - как вы можете использовать заменитель яиц в нашей аналогии с выпечкой.

Синтаксис для обработки исключений

Теперь давайте посмотрим, как мы действительно обрабатываем эти исключения в PL/SQL. Основная структура выглядит так:

BEGIN
-- Ваш код здесь
EXCEPTION
WHEN exception_name1 THEN
-- Обработка исключения 1
WHEN exception_name2 THEN
-- Обработка исключения 2
WHEN OTHERS THEN
-- Обработка всех других исключений
END;

Давайте разберем это:

  1. Мы пишем наш обычный код в блоке BEGIN.
  2. Если occurs исключение, программа переходит к блоку EXCEPTION.
  3. Мы можем обрабатывать конкретные исключения, используя предложения WHEN.
  4. Предложение WHEN OTHERS перехватывает любые исключения, которые мы не обрабатываем specifically.

Вот простой пример:

DECLARE
v_result NUMBER;
BEGIN
v_result := 10 / 0;  -- Это вызовет ошибку деления на ноль
DBMS_OUTPUT.PUT_LINE('Результат: ' || v_result);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('Ошибка: Нельзя делить на ноль!');
END;

В этом примере мы пытаемся разделить 10 на 0, что mathematically невозможно. Вместо того чтобы обрушиться, наша программа перехватывает исключение ZERO_DIVIDE и выводит дружелюбное сообщение об ошибке.

Приведение исключений

Иногда мы хотим создавать свои собственные исключения, когда выполняются определенные условия. Мы можем сделать это с помощью оператора RAISE. Это как быть судьей в футбольном матче - вы видите фол, вы свистите!

Вот как это работает:

DECLARE
v_age NUMBER := 15;
BEGIN
IF v_age < 18 THEN
RAISE_APPLICATION_ERROR(-20001, 'Должно быть 18 или старше');
END IF;
DBMS_OUTPUT.PUT_LINE('Добро пожаловать в клуб!');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Ошибка: ' || SQLERRM);
END;

В этом примере мы проверяем, достаточно ликому-то лет, чтобы войти в клуб. Если им менее 18 лет, мы вызываем исключение с пользовательским сообщением об ошибке. Предложение WHEN OTHERS перехватывает это исключение и выводит сообщение об ошибке.

Пользовательские исключения

Хотя PL/SQL предоставляет множество предопределенных исключений для_common ошибочных сценариев, иногда нам нужно создавать свои собственные. Это как inventing новая rule в нашей игре. Вот как мы можем это сделать:

DECLARE
e_invalid_name EXCEPTION;
v_name VARCHAR2(50) := 'J0hn';
BEGIN
IF NOT REGEXP_LIKE(v_name, '^[A-Za-z]+$') THEN
RAISE e_invalid_name;
END IF;
DBMS_OUTPUT.PUT_LINE('Имя действителен: ' || v_name);
EXCEPTION
WHEN e_invalid_name THEN
DBMS_OUTPUT.PUT_LINE('Ошибка: Имя должно содержать только буквы');
END;

В этом примере мы создали пользовательское исключение e_invalid_name. Мы вызываем это исключение, если имя содержит что-то кроме букв. Это позволяет нам обрабатывать эту конкретную ситуацию так, как это имеет смысл для нашей программы.

Предопределенные исключения

PL/SQL предоставляет набор предопределенных исключений дляcommon ошибочных сценариев. Это как иметь под рукой аптечку дляcommon травм. Вот некоторые из наиболее часто используемых:

Название исключения Описание
NO_DATA_FOUND Вызывается, когда SELECT INTO предложение не возвращает строк
TOO_MANY_ROWS Вызывается, когда SELECT INTO предложение возвращает более одной строки
ZERO_DIVIDE Вызывается при попытке разделить на ноль
DUP_VAL_ON_INDEX Вызывается при попытке вставить дублиручное значение в уникальный индекс
VALUE_ERROR Вызывается при арифметической, конвертационной, обрезке или ошибке ограничения размера

Давайте посмотрим пример использования предопределенного исключения:

DECLARE
v_emp_name VARCHAR2(50);
BEGIN
SELECT first_name INTO v_emp_name
FROM employees
WHERE employee_id = 1000;  -- Предположим, что этого ID нет

DBMS_OUTPUT.PUT_LINE('Имя сотрудника: ' || v_emp_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Ошибка: Сотрудник с таким ID не найден');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Ошибка: Найдено более одного сотрудника');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Произошла неожиданная ошибка: ' || SQLERRM);
END;

В этом примере мы пытаемся получить имя сотрудника. Если сотрудник не найден, мы перехватываем исключение NO_DATA_FOUND. Если somehow найдено несколько сотрудников, мы перехватываем исключение TOO_MANY_ROWS. Любые другие неожиданные ошибки перехватываются предложением WHEN OTHERS.

И вот и все,folks! Мы рассмотрели основы обработки исключений в PL/SQL. Помните, что обработка исключений - это как надевать ремень безопасности - это может показаться ненужным, когда все идет гладко, но это может спасти вам много проблем, когда что-то идет не так.

Практикуйте эти концепции, экспериментируйте с различными сценариями, и вскоре вы будете обрабатывать исключения как профи. Счастливого кодирования и пусть ваши программы всегда优雅но справляются с неожиданным!

Credits: Image by storyset