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
がグローバル変数であることを明示的に指定します。)