42.9. Сообщения и ошибки
42.9.1. Вывод сообщений и ошибок
Команда RAISE
предназначена для вывода сообщений и вызова ошибок.
RAISE [уровень
] 'формат
' [,выражение
[, ... ]] [ USINGпараметр
=значение
[, ... ] ]; RAISE [уровень
]имя_условия
[ USINGпараметр
=выражение
[, ... ] ]; RAISE [уровень
] SQLSTATE 'sqlstate
' [ USINGпараметр
=выражение
[, ... ] ]; RAISE [уровень
] USINGпараметр
=выражение
[, ... ]; RAISE ;
уровень
задаёт уровень важности ошибки. Возможные значения: DEBUG
, LOG
, INFO
, NOTICE
, WARNING
и EXCEPTION
. По умолчанию используется EXCEPTION
. EXCEPTION
вызывает ошибку (что обычно прерывает текущую транзакцию), остальные значения уровня
только генерируют сообщения с различными уровнями приоритета. Будут ли сообщения конкретного приоритета переданы клиенту или записаны в журнал сервера, или и то, и другое, зависит от конфигурационных переменных log_min_messages и client_min_messages. За дополнительными сведениями обратитесь к Главе 19.
После указания уровня
, если оно есть, можно задать строку формата
(это должна быть простая строковая константа, не выражение). Строка формата определяет вид текста об ошибке, который будет выдан. За строкой формата могут следовать необязательные выражения аргументов, которые будут вставлены в сообщение. Внутри строки формата знак %
заменяется строковым представлением значения очередного аргумента. Чтобы выдать символ %
буквально, продублируйте его (как %%
). Число аргументов должно совпадать с числом местозаполнителей %
в строке формата, иначе при компиляции функции возникнет ошибка.
В следующем примере символ %
будет заменён на значение v_job_id
:
RAISE NOTICE 'Вызов функции cs_create_job(%)', v_job_id;
При помощи USING
и последующих элементов параметр
= выражение
можно добавить дополнительную информацию к отчёту об ошибке. Все выражения
представляют собой строковые выражения. Возможные ключевые слова для параметра
следующие:
MESSAGE
Устанавливает текст сообщения об ошибке. Этот параметр не может использоваться, если в команде
RAISE
присутствуетформат
передUSING
.DETAIL
Предоставляет детальное сообщение об ошибке.
HINT
Предоставляет подсказку по вызванной ошибке.
ERRCODE
Устанавливает код ошибки (
SQLSTATE
). Код ошибки задаётся либо по имени, как показано в Приложении A, или напрямую, пятисимвольный кодSQLSTATE
.COLUMN
CONSTRAINT
DATATYPE
TABLE
SCHEMA
Предоставляет имя соответствующего объекта, связанного с ошибкой.
Этот пример прерывает транзакцию и устанавливает сообщение об ошибке с подсказкой:
RAISE EXCEPTION 'Несуществующий ID --> %', user_id USING HINT = 'Проверьте ваш пользовательский ID';
Следующие два примера демонстрируют эквивалентные способы задания SQLSTATE
:
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
У команды RAISE
есть и другой синтаксис, в котором в качестве главного аргумента используется имя или код SQLSTATE
ошибки. Например:
RAISE division_by_zero; RAISE SQLSTATE '22012';
Предложение USING
в этом синтаксисе можно использовать для того, чтобы переопределить стандартное сообщение об ошибке, детальное сообщение, подсказку. Ещё один вариант предыдущего примера:
RAISE unique_violation USING MESSAGE = 'ID пользователя уже существует: ' || user_id;
Ещё один вариант — использовать RAISE USING
или RAISE
, а всё остальное записать в списке уровень
USINGUSING
.
И заключительный вариант, в котором RAISE
не имеет параметров вообще. Эта форма может использоваться только в секции EXCEPTION
блока и предназначена для того, чтобы повторно вызвать ошибку, которая сейчас перехвачена и обрабатывается.
Примечание
До версии PostgreSQL 9.1 команда RAISE
без параметров всегда вызывала ошибку с выходом из блока, содержащего активную секцию EXCEPTION
. Эту ошибку нельзя было перехватить, даже если RAISE
в секции EXCEPTION
поместить во вложенный блок со своей секцией EXCEPTION
. Это было сочтено удивительным и не совместимым с Oracle PL/SQL.
Если в команде RAISE EXCEPTION
не задано ни имя, ни код SQLSTATE
, по умолчанию выдаётся raise_exception
(P0001
). Если не задан текст сообщения, по умолчанию в качестве этого текста передаётся имя условия или код SQLSTATE.
Примечание
При задании SQLSTATE
кода необязательно использовать только список предопределённых кодов ошибок. В качестве кода ошибки может быть любое пятисимвольное значение, состоящее из цифр и/или ASCII символов в верхнем регистре, кроме 00000
. Не рекомендуется использовать коды ошибок, которые заканчиваются на 000
, потому что так обозначаются коды категорий. И чтобы их перехватить, нужно перехватывать целую категорию.
42.9.2. Проверка утверждений
Оператор ASSERT
представляет удобное средство вставлять отладочные проверки в функции PL/pgSQL.
ASSERTусловие
[ ,сообщение
];
Здесь условие
— это логическое выражение, которое, как ожидается, должно быть всегда истинным; если это так, оператор ASSERT
больше ничего не делает. Если же оно возвращает ложь или NULL, этот оператор выдаёт исключение ASSERT_FAILURE
. (Если ошибка происходит при вычислении условия
, она выдаётся как обычная ошибка.)
Если в нём задаётся необязательное сообщение
, результат этого выражения (если он не NULL) заменяет сообщение об ошибке по умолчанию «assertion failed» (нарушение истинности), в случае, если условие
не выполняется. В обычном случае, когда условие утверждения выполняется, выражение сообщения
не вычисляется.
Проверку утверждений можно включить или отключить с помощью конфигурационного параметра plpgsql.check_asserts
, принимающего логическое значение; по умолчанию она включена (on
). Если этот параметр отключён (off
), операторы ASSERT
ничего не делают.
Учтите, что оператор ASSERT
предназначен для выявления программных дефектов, а не для вывода обычных ошибок (для этого используется оператор RAISE
, описанный выше).
42.9. Errors and Messages
42.9.1. Reporting Errors and Messages
Use the RAISE
statement to report messages and raise errors.
RAISE [level
] 'format
' [,expression
[, ... ]] [ USINGoption
=expression
[, ... ] ]; RAISE [level
]condition_name
[ USINGoption
=expression
[, ... ] ]; RAISE [level
] SQLSTATE 'sqlstate
' [ USINGoption
=expression
[, ... ] ]; RAISE [level
] USINGoption
=expression
[, ... ]; RAISE ;
The level
option specifies the error severity. Allowed levels are DEBUG
, LOG
, INFO
, NOTICE
, WARNING
, and EXCEPTION
, with EXCEPTION
being the default. EXCEPTION
raises an error (which normally aborts the current transaction); the other levels only generate messages of different priority levels. Whether messages of a particular priority are reported to the client, written to the server log, or both is controlled by the log_min_messages and client_min_messages configuration variables. See Chapter 19 for more information.
After level
if any, you can specify a format
string (which must be a simple string literal, not an expression). The format string specifies the error message text to be reported. The format string can be followed by optional argument expressions to be inserted into the message. Inside the format string, %
is replaced by the string representation of the next optional argument's value. Write %%
to emit a literal %
. The number of arguments must match the number of %
placeholders in the format string, or an error is raised during the compilation of the function.
In this example, the value of v_job_id
will replace the %
in the string:
RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;
You can attach additional information to the error report by writing USING
followed by option
= expression
items. Each expression
can be any string-valued expression. The allowed option
key words are:
MESSAGE
Sets the error message text. This option can't be used in the form of
RAISE
that includes a format string beforeUSING
.DETAIL
Supplies an error detail message.
HINT
Supplies a hint message.
ERRCODE
Specifies the error code (SQLSTATE) to report, either by condition name, as shown in Appendix A, or directly as a five-character SQLSTATE code.
COLUMN
CONSTRAINT
DATATYPE
TABLE
SCHEMA
Supplies the name of a related object.
This example will abort the transaction with the given error message and hint:
RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID';
These two examples show equivalent ways of setting the SQLSTATE:
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
There is a second RAISE
syntax in which the main argument is the condition name or SQLSTATE to be reported, for example:
RAISE division_by_zero; RAISE SQLSTATE '22012';
In this syntax, USING
can be used to supply a custom error message, detail, or hint. Another way to do the earlier example is
RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;
Still another variant is to write RAISE USING
or RAISE
and put everything else into the level
USINGUSING
list.
The last variant of RAISE
has no parameters at all. This form can only be used inside a BEGIN
block's EXCEPTION
clause; it causes the error currently being handled to be re-thrown.
Note
Before PostgreSQL 9.1, RAISE
without parameters was interpreted as re-throwing the error from the block containing the active exception handler. Thus an EXCEPTION
clause nested within that handler could not catch it, even if the RAISE
was within the nested EXCEPTION
clause's block. This was deemed surprising as well as being incompatible with Oracle's PL/SQL.
If no condition name nor SQLSTATE is specified in a RAISE EXCEPTION
command, the default is to use raise_exception
(P0001
). If no message text is specified, the default is to use the condition name or SQLSTATE as message text.
Note
When specifying an error code by SQLSTATE code, you are not limited to the predefined error codes, but can select any error code consisting of five digits and/or upper-case ASCII letters, other than 00000
. It is recommended that you avoid throwing error codes that end in three zeroes, because these are category codes and can only be trapped by trapping the whole category.
42.9.2. Checking Assertions
The ASSERT
statement is a convenient shorthand for inserting debugging checks into PL/pgSQL functions.
ASSERTcondition
[ ,message
];
The condition
is a Boolean expression that is expected to always evaluate to true; if it does, the ASSERT
statement does nothing further. If the result is false or null, then an ASSERT_FAILURE
exception is raised. (If an error occurs while evaluating the condition
, it is reported as a normal error.)
If the optional message
is provided, it is an expression whose result (if not null) replaces the default error message text “assertion failed”, should the condition
fail. The message
expression is not evaluated in the normal case where the assertion succeeds.
Testing of assertions can be enabled or disabled via the configuration parameter plpgsql.check_asserts
, which takes a Boolean value; the default is on
. If this parameter is off
then ASSERT
statements do nothing.
Note that ASSERT
is meant for detecting program bugs, not for reporting ordinary error conditions. Use the RAISE
statement, described above, for that.