44.8. PL/Tcl 中的错误处理#
PL/Tcl 函数中或通过 PL/Tcl 函数调用的 Tcl 代码可能会引发错误,方法是执行一些无效操作或使用 Tclerror
命令或 PL/Tcl 的elog
命令生成错误。此类错误可以使用 Tclcatch
命令在 Tcl 中捕获。如果未捕获错误,而是允许错误传播到 PL/Tcl 函数执行的顶级,则该错误将作为 SQL 错误报告在函数的调用查询中。
相反,在 PL/Tcl 的spi_exec
、spi_prepare
和spi_execp
命令中发生的 SQL 错误会报告为 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
是一个全局变量。)