2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:开发版
不受支持的版本:11 / 10 / 9.6

42.8. PL/Tcl 中的错误处理 #

PL/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 版本号,其他单词是提供有关错误详细信息的字段名/值对。始终提供字段 SQLSTATEconditionmessage(前两个分别表示错误代码和条件名称,如 附录 A 中所示)。可能存在的字段包括 detailhintcontextschematablecolumndatatypeconstraintstatementcursor_positionfilenamelinenofuncname

使用 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 是一个全局变量。)

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表单 报告文档问题。