Содержание

Предыдущий раздел

Сравнение с NULL

Следующий раздел

Тип параметра не соответствует подготовленному плану

Обработка ошибок и исключений в pl/pgsql коде

Обработка исключений в хранимых процедурах и анонимных блоках возможна только внутри конструкции

BEGIN
  -- Тут располагается потенциально опасный код
EXCEPTION
  WHEN '<идентификатор_ошибки>' THEN
    -- Тут находится код, обрабатывающий исключение
END

Для того, чтобы обработать исключение, необходимо указать идентификатор ошибки, который будет обрабатываться. Коды всех ошибок и их идентификаторов можно найти на странице PostgreSQL Error Codes официальной документации.

К примеру, необходимо обрабатывать ситуацию, когда происходит запись двух одинаковых значений в уникальное поле таблицы

Выполнив нижеприведенный код:

DO $$
BEGIN
  CREATE TABLE test_table(
    name varchar UNIQUE
  );
  INSERT INTO test_table(name) VALUES('my name');
  INSERT INTO test_table(name) VALUES('my name');
END $$;

получим исключение:

ERROR:  duplicate key value violates unique constraint "test_table_name_key"
DETAIL:  Key (name)=(my name) already exists.
CONTEXT:  SQL statement "INSERT INTO test_table(name) VALUES('my name')"
PL/pgSQL function "inline_code_block" line 7 at SQL statement

по тексту исключения можно попробовать найти ошибку на странице PostgreSQL Error Codes, но это не всегда бывает возможно. Поэтому надо узнать код ошибки однозначно. Для этого надо вывести в лог значение специальной переменной SQLSTATE, которая и содержит искомый код.

DO $$
BEGIN
  CREATE TABLE test_table(
    name varchar UNIQUE
  );
  INSERT INTO test_table(name) VALUES('my name');
  INSERT INTO test_table(name) VALUES('my name');
EXCEPTION
  WHEN others THEN
    RAISE NOTICE 'SQLSTATE: %', SQLSTATE;
    RAISE;
END $$;

в логе виден код ошибки (23505):

NOTICE:  SQLSTATE: 23505
ERROR:  duplicate key value violates unique constraint "test_table_name_key"
DETAIL:  Key (name)=(my name) already exists.
CONTEXT:  SQL statement "INSERT INTO test_table(name) VALUES('my name')"
PL/pgSQL function "inline_code_block" line 7 at SQL statement

другое дело. По таблице кодов ошибок сразу находим идентификатор ошибки, который надо обрабатывать

Error Code Condition Name
23505 unique_violation

изменяю предыдущий код:

DO $$
BEGIN
  CREATE TABLE test_table(
    name varchar UNIQUE
  );
  INSERT INTO test_table(name) VALUES('my name');
  INSERT INTO test_table(name) VALUES('my name');
EXCEPTION
  WHEN unique_violation THEN
    RAISE NOTICE 'Illegal operation: %', SQLERRM;
END $$;

Результат:

PL/pgSQL function "inline_code_block" line 3 at SQL statement
NOTICE:  Illegal operation: duplicate key value violates unique constraint "test_table_name_key"

Исключительная ситуация обработана.

Совет

Бывают ситуацию, когда надо защититься от всех возможных ошибок, которые могут возникнуть. В этом случае поможет специальный идентификатор ошибки others. С помощью этого идентификатора можно ловить любые типы исключения, кроме query_canceled

comments powered by Disqus