Вызов и перехват исключения
На этом шаге вы научитесь обрабатывать ошибки времени выполнения, известные как исключения. Необработанное исключение немедленно завершит выполнение вашей функции. Сначала вы создадите функцию, которая завершается с ошибкой, а затем измените ее для корректного перехвата исключения.
Давайте создадим функцию simple_divide, которая выполняет целочисленное деление. Эта функция имеет потенциальный недостаток: она завершится с ошибкой, если вы попытаетесь выполнить деление на ноль.
CREATE OR REPLACE FUNCTION simple_divide(numerator INTEGER, denominator INTEGER)
RETURNS INTEGER AS $$
BEGIN
RETURN numerator / denominator;
END;
$$ LANGUAGE plpgsql;
Сначала вызовите функцию с допустимыми входными данными, чтобы убедиться, что она работает правильно:
SELECT simple_divide(10, 2);
Вывод будет результатом деления:
simple_divide
---------------
5
(1 row)
Теперь вызовите функцию с нулевым знаменателем, чтобы вызвать исключение:
SELECT simple_divide(10, 0);
Эта команда завершится с ошибкой и вернет сообщение об ошибке. Выполнение функции прерывается.
ERROR: division by zero
CONTEXT: PL/pgSQL function simple_divide(integer,integer) line 3 at RETURN
Это необработанное исключение. Чтобы предотвратить аварийное завершение функции, вы можете использовать блок EXCEPTION. Давайте создадим новую функцию safe_divide, которая включает обработку ошибок.
CREATE OR REPLACE FUNCTION safe_divide(numerator INTEGER, denominator INTEGER)
RETURNS INTEGER AS $$
BEGIN
RETURN numerator / denominator;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE 'Error: Cannot divide by zero.';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Вот как работает блок EXCEPTION:
BEGIN...END;: Определяет блок кода.
EXCEPTION: Этот ключевое слово начинает раздел обработки исключений.
WHEN division_by_zero THEN: Указывает, что следующий код должен выполняться только при возникновении ошибки division_by_zero.
- Код внутри обработчика генерирует уведомление и возвращает
NULL вместо аварийного завершения.
Теперь вызовите новую функцию safe_divide с нулевым знаменателем:
SELECT safe_divide(10, 0);
На этот раз функция не завершается с ошибкой. Она перехватывает исключение, отображает ваше пользовательское уведомление и возвращает NULL.
NOTICE: Error: Cannot divide by zero.
safe_divide
-------------
(1 row)
Вы успешно перехватили конкретное исключение и контролировали вывод функции.