2012-03-23 19 views
1

エラーが発生した後にトランザクションを自動的にロールバックするために、PostgreSQLストアドプロシージャに例外処理を追加します。PostgreSQLで例外をキャッチした後に呼び出し関数にエラーの詳細を返す

私の問題は、一度例外を捕まえたら、エラーの詳細をlibpqを使う呼び出し側のCプログラムに返すことができないということです。

重大度、SQLSTATE、プライマリ、詳細およびヒントはすべてnullです。例外をキャッチした後にこれらを返す方法はありますか?

これらの値を収集するために使用するlibpq関数はPQresultErrorField()です。

答えて

1

私は最近complete solution how to add a CONTEXT to error messages on dba.SEを投稿しました。そのトリックは、エラー/警告/通知/などを呼び出す関数を呼び出すことです。

私はあなたのケースが異なる可能性があることを認識しました。私の回避策は、自分自身で発生させた例外にCONTEXTを追加することです。

あなたは、トランザクションがロールバックされる前にものを行うための例外をキャッチした場合、あなたは例外ブロックの最後にパラメータを指定せずにRAISEを追加することもできます。

RAISE; 

manual about RAISE

The last variant of RAISE has no parameters at all. This form can only be used inside a BEGIN block's EXCEPTION clause; it causes the error currently being handled to be re-thrown.

しかし、@araqnidが指摘しているように、とにかくエラーを伝えようとしている場合は例外ブロックには使用されず、すべてがロールバックされます。この解決策は、特定の変更が永続的でロールバックできないまれなケース(dblinkなど)にのみ有効です。

2

例外よりも自動的にpostgresqlトランザクションがロールバックされます。例外をキャッチするのは、エラーを有効に回復し、伝播しない場合にのみ便利です。

+0

正確に。おそらくOPに2つ以上の接続を持つアプリケーションがあり、2フェーズコミットが必要ですか? – wildplasser

+0

それを詳しく教えていただけますか?しかし、カーソルを返すプロシージャを呼び出すと、まったく同じことが仮定されていました。繰り返し実行したいときに、例外をトリガします。これは私が得るものです。 "エラー:現在のトランザクションは中断され、トランザクションブロック "。だから、私が理解していることから、ロールバックするために私の手続きで例外をキャッチしなければならない。私が間違っている? –

+0

良い点。すべてがロールバックされ、何かをクリーンアップしようとしても使用されません。ただし、ロールバックされないdblink呼び出しのようなまれな例外があります。このような場合にOPが必要とするのは、例外ブロックの最後に「RAISE;」と呼ぶことです。私はそれに応じて私の答えを修正しました。 –