↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6
历史版本。 PostgreSQL 11 已结束支持。 2023-11-09. 请参阅 当前版本手册.

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

PL/Tcl 函数内的 Tcl 代码,或从 PL/Tcl 函数调用的 Tcl 代码,都可能引发错误:要么是执行了某个非法操作,要么是通过 Tcl 的 error 命令或 PL/Tcl 的 elog 命令主动生成错误。在 Tcl 中,可以使用 catch 命令捕获这类错误。如果错误没有被捕获,而是一路传播到 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"} {
            # 处理表不存在的情况
        } else {
            # 处理其他类型的 SQL 错误
        }
    }
}

(双冒号显式指定 errorCode 是一个全局变量。)

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.