Обработка ошибок в PL/Tcl
Эта страница переведена при помощи нейросети GigaChat.
Код Tcl внутри функции PL/Tcl или вызываемый из нее может вызвать ошибку, выполнив некорректную операцию или сгенерировав ошибку с помощью команды Tcl error
или команды PL/Tcl elog
. Такие ошибки могут быть перехвачены в Tcl с использованием команды Tcl catch
. Если ошибка не будет поймана и будет распространяться до верхнего уровня выполнения функции PL/Tcl, она будет сообщена как ошибка SQL в запросе вызова этой функции.
Наоборот, ошибки SQL, которые происходят в командах PL/Tcl spi_exec
, spi_prepare
и spi_execp
, сообщаются как ошибки Tcl, поэтому они могут быть перехвачены командой Tcl catch
. Каждая из этих команд PL/Tcl выполняет свою SQL-операцию в подтранзакции, которая откатывается при ошибке, так что любая частично завершенная операция автоматически очищается. Снова, если ошибка распространяется до верхнего уровня без перехвата, она превращается обратно в ошибку SQL.
Tcl предоставляет переменную errorCode
, которая может представлять дополнительную информацию об ошибке в форме, удобной для интерпретации программами Tcl. Содержимое находится в формате списка Tcl, и первое слово идентифицирует подсистему или библиотеку, сообщающую об ошибке; за этим содержание предоставляется конкретной подсистеме или библиотеке. Для ошибок базы данных, о которых сообщают команды PL/Tcl, первым словом является POSTGRES
, вторым словом является номер версии PostgreSQL, а дополнительные слова представляют собой пары имя поля/значение, предоставляющие подробную информацию об ошибке. Поля SQLSTATE
, condition
и message
всегда предоставляются (первые два представляют код ошибки и имя условия, показанные в Приложении A). Поля, которые могут присутствовать, включают detail
, hint
, context
, schema
, table
, column
, datatype
, constraint
, statement
, cursor_position
, filename
, lineno
и funcname
.
Удобный способ работы с информацией PL/Tcl errorCode
- загрузить ее в массив, чтобы имена полей стали индексами массива. Код для этого мог бы выглядеть так:
if {[catch { spi_exec $sql_command }]} {
if {[lindex $::errorCode 0] == "POSTGRES"} {
array set errorArray $::errorCode
if {$errorArray(condition) == "undefined_table"} {
# deal with missing table
} else {
# deal with some other type of SQL error
}
}
}
Двойные двоеточия явно указывают, что errorCode
является глобальной переменной.