Postgresql 中文操作指南

44.8. Error Handling in PL/Tcl #

Tcl 代码或从 PL/Tcl 函数调用的 Tcl 代码可引发错误,方法是执行某些无效操作或使用 Tcl error 命令或 PL/Tcl 的 elog 命令生成错误。可以使用 Tcl catch 命令在 Tcl 中捕获此类错误。如果错误未被捕获,但允许传播到 PL/Tcl 函数执行的顶级,则将其报告为函数的调用查询中的 SQL 错误。

相反,在 PL/Tcl 的 spi_execspi_preparespi_execp 命令中发生的 SQL 错误报告为 Tcl 错误,因此可由 Tcl 的 catch 命令捕获。(这些 PL/Tcl 命令中的每个命令都在子事务中运行其 SQL 操作,并在出错时回滚,以便自动清理所有部分完成的操作。)同样,如果错误传播到顶级而未被捕获,则会变成 SQL 错误。

Tcl 提供一个 errorCode_变量,它可以用一种对 Tcl 程序易于解释的形式表示有关错误的附加信息。内容采用 Tcl 列表格式,第一个词标识报告错误的子系统或库;此后内容留给各个子系统或库。对于 PL/Tcl 命令报告的数据库错误,第一个词是 _POSTGRES,第二个词是 PostgreSQL 版本号,其他词是提供错误详细信息的字段名/值对。字段 SQLSTATEcondition_和 _message_始终提供(前两个表示错误代码和条件名称,如 Appendix A所示)。可能存在的字段包括 _detailhintcontextschematablecolumndatatypeconstraintstatementcursor_positionfilenamelineno_和 _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 是一个全局变量。)