PL/Tcl関数中の、あるいはPL/Tcl関数から呼ばれるTclコードは、無効な演算の実行により、あるいはTclのerrorコマンドやPL/Tclのelogコマンドを使ってエラーを生成することにより、エラーとなることがありえます。
これらエラーはTclのcatchコマンドを使ってTcl内で捕捉することができます。
あるエラーが捕捉されず、PL/Tcl関数実行のトップレベルに伝播することが許容されているなら、関数が呼び出している問合せにおけるSQエラーとして報告されます。
逆に、PL/Tclのspi_exec、spi_prepare、spi_execpコマンドの中で起きるSQLエラーは、Tclのエラーとして報告され、したがって、これらはTclのcatchコマンドにより捕捉可能です。
(各々のPL/Tclコマンドは、エラー時にロールバックするSQL操作をサブトランザクション中で実行するので、部分的に完了した操作は自動的に後始末されます。)
ここでも同様に、捕捉されることなくトップレベルに伝播するならSQLエラーに戻ります。
Tclは、Tclプログラムで解釈しやすい形式でエラーに関する追加情報を表現できるerrorCode変数を提供します。
変数の中身はTclリスト形式で、1番目の語でエラーを報告したサブシステムまたはライブラリを識別します。それ以降の内容は個々のサブシステムやライブラリに任されています。
PL/Tclコマンドで報告されるデータベースエラーむけには、1番目の語がPOSTGRES、2番目の語がPostgreSQLのバージョン番号で、それ続く語はエラーの詳細情報を提供するフィールド名と値の組です。
フィールドSQLSTATE、condition、およびmessageは常に与えられます(最初の2つは付録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がグローバル変数であることを明示的に指定します。)