39.9. Ошибки и сообщения#

39.9. Ошибки и сообщения

39.9. Ошибки и сообщения #

39.9.1. Сообщения об ошибках и сообщения #

Используйте оператор RAISE для вывода сообщений и генерации ошибок.

RAISE [ level ] 'format' [, expression [, ... ]] [USING option { = | := } expression [, ... ]];
RAISE [ level ] condition_name [USING option { = | := } expression [, ... ]];
RAISE [ level ] SQLSTATE 'sqlstate' [USING option { = | := } expression [, ... ]];
RAISE [ level ] USING option { = | := } expression [, ... ];
RAISE ;

Опция level определяет уровень серьезности ошибки. Допустимые уровни: DEBUG, LOG, INFO, NOTICE, WARNING и EXCEPTION, по умолчанию используется EXCEPTION. Уровень EXCEPTION вызывает ошибку (что обычно приводит к прерыванию текущей транзакции), а остальные уровни только генерируют сообщения различных приоритетов. Отображение сообщений определенного приоритета для клиента, запись в журнал сервера или и то, и другое контролируется переменными конфигурации log_min_messages и client_min_messages. Дополнительную информацию см. в разделе Глава 18.

В первом варианте синтаксиса, после level, если он указан, указывается строка format (которая должна быть простой строковой константой, а не выражением). Строка формата определяет вид текста сообщения об ошибке, которое будет выведено. За строкой формата могут следовать необязательные выражения аргументов, которые будут вставлены в сообщение. Внутри строки формата % заменяется строковым представлением значения следующего необязательного аргумента. Запишите %%, чтобы вывести символ % буквально. Количество аргументов должно соответствовать количеству местозаполнителей % в строке формата, иначе при компиляции функции возникнет ошибка.

В этом примере значение v_job_id заменит символ % в строке:

RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;

Во втором и третьем вариантах синтаксиса в condition_name и sqlstate соответственно указывается имя условия ошибки или пятисимвольный код SQLSTATE. Действительные имена условия ошибок и предопределённые коды SQLSTATE приведены в Приложение A.

Вот примеры использования condition_name и sqlstate:

RAISE division_by_zero;
RAISE WARNING SQLSTATE '22012';

В любом из этих вариантов синтаксиса вы можете добавить дополнительную информацию к сообщению об ошибке, написав USING с последующим перечислением элементов option = expression. Все выражения expression представляют собой строковые выражения. Допустимые ключевые слова для option следующие:

MESSAGE #

Устанавливает текст сообщения об ошибке. Этот параметр не может быть использован в первом варианте синтаксиса, так как сообщение в нем уже задано.

DETAIL #

Предоставляет подробное сообщение об ошибке.

HINT #

Предоставляет подсказку сообщения.

ERRCODE #

Указывает код ошибки (SQLSTATE) для отчета, либо по имени условия, как показано в Приложение A, либо напрямую в виде пятисимвольного кода SQLSTATE. Эта опция не может быть использована во втором или третьем варианте синтаксиса, так как в них код ошибки уже задан.

COLUMN
CONSTRAINT
DATATYPE
TABLE
SCHEMA #

Предоставляет имя связанного объекта.

Этот пример прерывает транзакцию с заданным сообщением об ошибке и подсказкой:

RAISE EXCEPTION 'Nonexistent ID --> %', user_id
      USING HINT = 'Please check your user ID';

Эти два примера показывают эквивалентные способы установки SQLSTATE:

RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';

Другой способ получить тот же результат:

RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;

В четвертом варианте синтаксиса, также можно использовать RAISE USING или RAISE level USING, и поместить все остальное в список USING.

Последний вариант команды RAISE не имеет параметров вообще. Эта форма может использоваться только внутри предложения EXCEPTION блока BEGIN; она вызывает повторное возбуждение обрабатываемой в данный момент ошибки.

Примечание

До версии PostgreSQL 9.1, команда RAISE без параметров интерпретировалась как повторное возбуждение ошибки из блока, содержащего активный обработчик исключений. Таким образом, вложенная в этот обработчик EXCEPTION не могла ее перехватить, даже если команда RAISE находилась в блоке вложенной EXCEPTION. Это было считано неожиданным и несовместимым с PL/SQL Oracle.

Если ни имя условия, ни SQLSTATE не указаны в команде RAISE EXCEPTION, по умолчанию используется raise_exception (P0001). Если текст сообщения не указан, по умолчанию используется имя условия или SQLSTATE в качестве текста сообщения.

Примечание

При указании кода ошибки по коду SQLSTATE вы не ограничены предопределенными кодами ошибок, но можете выбрать любой код ошибки, состоящий из пяти цифр и/или заглавных букв ASCII, кроме 00000. Рекомендуется избегать выбрасывания кодов ошибок, оканчивающихся на три нуля, поскольку они являются кодами категорий и могут быть перехвачены только путем перехвата всей категории.

39.9.2. Проверка утверждений #

ASSERT - это удобное сокращение для вставки отладочных проверок в функции PL/pgSQL.

ASSERT condition [ , message ];

condition - это логическое выражение, которое ожидается всегда true; если это так, оператор ASSERT не выполняет никаких дополнительных действий. Если результат ложный или null, то возникает исключение ASSERT_FAILURE. (Если происходит ошибка при вычислении условия condition, она сообщается как обычная ошибка).

Если предоставлен необязательный параметр message, то это выражение, результат которого (если не является пустым) заменяет текст сообщения об ошибке по умолчанию assertion failed, если condition не выполняется. Выражение message не вычисляется в обычном случае, когда утверждение выполняется успешно.

Все проверки утверждений могут быть включены или отключены с помощью параметра конфигурации plpgsql.check_asserts, который принимает значение типа Boolean; значение по умолчанию - on. Если этот параметр установлен в значение off, то операторы ASSERT не выполняют никаких действий.

Обратите внимание, что ASSERT предназначен для обнаружения ошибок в программе, а не для сообщения об обычных условиях ошибок. Для этого используйте оператор RAISE, описанный выше.