Исключения в PL/pgSQL

«Пост-Грэс-Кью-Эл» свободная объектно-реляционная СУБД. Обмениваемся вопросами и ответами о её работе.
Ответить
AntonS
Сообщения: 108
Зарегистрирован: Пт июн 03, 2022 8:51 am

Исключения в PL/pgSQL

Сообщение AntonS »

Синтаксис процедурного языка PostgreSQL PL/pgSQL сильно напоминает PL/SQL

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

Код: Выделить всё

CREATE OR REPLACE FUNCTION hr.getlastname (p_name text) RETURNS varchar AS $function$
DECLARE
    v_lastname TEXT;
BEGIN
    SELECT last_name INTO STRICT v_lastname FROM employees WHERE UPPER(first_name) = UPPER(p_name);
    RETURN v_lastname;
EXCEPTION
  WHEN no_data_found THEN
    RAISE NOTICE 'Не нашлось строк для %', p_name;
        RETURN 'Неизвестно';
  WHEN too_many_rows THEN
    RAISE NOTICE 'Неоднозначный набор строк для %', p_name;
        RETURN 'Неизвестно';
  WHEN OTHERS THEN
    RAISE NOTICE 'Непредвиденная ошибка';
    RAISE;
END;
$function$
LANGUAGE PLPGSQL
 STABLE;
Как показано в документации, если в контструкции SELECT INTO добавлено указание STRICT, то команда должна вернуть ровно одну строку или произойдёт ошибка во время выполнения: либо NO_DATA_FOUND (нет строк), либо TOO_MANY_ROWS (более одной строки) и иожно это использовать в секции исключений блока для обработки ошибок:

Код: Выделить всё

demo=# SELECT getlastname('Jack');
 getlastname 
-------------
 Livingston
(1 row)

demo=# SELECT getlastname('Bob');
NOTICE:  Не найден сотрудник Bob
 getlastname 
-------------
 Неизвестно
(1 row)

demo=# SELECT getlastname('Peter');
NOTICE:  Найдено более одного сотрудника Peter
 getlastname 
-------------
 Неизвестно
(1 row)
Если указание STRICT отсутствует в предложении INTO, то цели присваивается первая строка, возвращённая командой; или NULL, если команда не вернула строки, при этом в блок обработки ошибок функция не переходит:

Код: Выделить всё

demo=# SELECT getlastname2('Bob');
 getlastname2
--------------

(1 row)

demo=# SELECT getlastname2('Peter');
 getlastname2
--------------
 Vargas
(1 row)
Для случая, если не вернулось строк, возможно проверять специальную переменную FOUND, для случая если вернулось более одной строки это не подходит.
Ответить