2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6

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 是一個全域性變數。)

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。