PL/Tcl 函数内部或由 PL/Tcl 函数调用的 Tcl 代码可能会引发错误,无论是通过执行某些无效操作,还是通过使用 Tcl 的 error
命令或 PL/Tcl 的 elog
命令生成错误。此类错误可以在 Tcl 中使用 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"} { # deal with missing table } else { # deal with some other type of SQL error } } }
(双冒号显式指定 errorCode
是一个全局变量。)
如果您在文档中发现任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。