Redrock Postgres 搜索 英文
版本: 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

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

PL/Tcl 函数内或被 PL/Tcl 函数调用的 Tcl 代码可能会引发错误,方法是对一些无效操作执行操作,或使用 Tcl error 命令或 PL/Tcl 的 elog 命令来生成错误。此类错误可以在 Tcl 内使用 Tcl catch 命令捕获。如果错误没有被捕获,而是被允许传播到 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 是一个全局变量。)