TOP書籍連動> 例外処理
まるごと PostgreSQL!
PostgreSQLとOracleによるデータベース相互移行マニュアル

第13回:まとめ
著者:奥畑 裕樹(OKUHATA, Hiroki)   2006/1/6
1   2  次のページ
例外処理

   最終回となる今回は、ストアドプロシーシャの移行の説明のあと、全体のまとめを紹介します。

   PostgreSQLには、Oracleにあるような型付けされた例外や例外ハンドラの機構は用意されていません。PostgreSQLのマニュアルには、例外処理機構について次のように説明されています。

   …現時点では(データ型の書式エラー、浮動小数点エラー、解析エラーといったもののうち)、何が実際にその中断を引き起こしたのかを通知することはできません。そして、この段階ではバックエンドは不整合状態にあるので上位のエクゼキュータに戻したり、コマンドをさらに発行するとデータベース全体を壊してしまうかもしれません。

   したがって、現段階で関数やトリガプロシージャ実行中に中断が起きたときに、PL/pgSQLができることは、どの関数のどこ(行番号と文の型)で発生したのか知らせるフィールドをいくつかメッセージに追加することだけです。このエラーは常に関数の実行を停止します。

   この説明にあるように、PostgreSQLは処理が失敗した原因を報告することができません。このため、失敗の種類に応じた処理を取ることもできません。現時点で、PostgreSQLのRAISE文にできることは、単にエラーを発生させて、エラーを記録することだけです。

   そこで、PL/SQLにおけるEXCEPTIONブロックは、そのまま削除することで対応するようにします。

   PostgreSQL8.0では、EXCEPTION句を使って発生したエラーを捕捉することができるようになりました。エラーを捕捉すると、対応するBEGIN ENDブロック内部のINSERTやUPDATE文などがロールバックされます。捕捉できるエラーの種類と名前はOracleとPostgreSQLで異なりますので、詳しくはそれぞれのマニュアルを参照してください。下記は0による除算エラーを捕捉する場合の例です。

CREATE OR REPLACE PROCEDURE
   CATCH_ERR_TEST( X IN NUMBER ) IS
   Y NUMBER;
BEGIN
   Y := 1 / X;
EXCEPTION
   WHEN ZERO_DIVIDE THEN
      DBMS_OUTPUT.PUT_LINE('0除算エラーを捕捉しました。');
END;

リスト27:Oracleで除算エラーを捕捉する場合の例

   下記が実行結果です。

BEGIN
     CATCH_ERR_TEST(0);
END;
0除算エラーを捕捉しました。

   これをPostgreSQLで表すと下記のようになります。

CREATE OR REPLACE FUNCTION CATCH_ERR_TEST(INTEGER)
   RETURNS VOID AS '
DECLARE
   x ALIAS FOR $1;
   y integer;
BEGIN
   y := 1 / x;
   RETURN;
EXCEPTION
   WHEN division_by_zero THEN
      RAISE NOTICE ''0除算エラーを捕捉しました。'';
      RETURN;
END;
' LANGUAGE 'plpgsql';

リスト28:PostgreSQLで除算エラーを捕捉する場合の例

   実行した結果は次のようになります。

% SELECT CATCH_ERR_TEST(0);

NOTICE: 0除算エラーを捕捉しました。
トランザクション処理

   PostgreSQLのストアドプロシージャの内部では、トランザクションを開始したり、終了したりすることができません。つまり、ネストしたトランザクションに対応していないのです。また、セーブポイントにも対応していません。

   これは、PostgreSQLのストアドプロシージャが、常に呼び出し側で確立した1つのトランザクションの中で実行されるためです。ただし、RAISE EXCEPTION文を使用してエラーを発生させ、現のトランザクションをアボートすることは可能です。

   PostgreSQLのストアドプロシージャは、現段階では、長い業務ロジックを実装するのには向いていないといえるでしょう。

   PostgreSQL8.0では、セーブポイントに対応しました。トランザクションの内部で部分的に処理をロールバックさせることが可能になり、長い業務ロジックが実装しやすくなりました。詳しくはPostgreSQLマニュアルの「SAVEPOINT」および「ROLLBACKTO SAVEPOINT」などのSQLコマンドを参照してください。


動的SQL

   PL/SQL、PL/pgSQLともに、動的に作成したSQL文を実行できる機能があります。ただしPL/pgSQLでは、関数本体全体を1つの文字列として処理するしくみのため、注意が必要です。quote_ident(text)関数と、quote_literal(text)関数による、文字列のエスケープ処理が必要になります。詳しくは、PostgreSQLのマニュアルを参照してください。


前方参照

   PL/pgSQLでは、ある関数中で別の関数名を前方参照することができます。PL/SQLのように、事前の宣言は必要ありません。これは、PL/pgSQLのストアドプロシージャの中で使われる識別子が、宣言時ではなく実行時に名前解決されるためです。

   このため、PL/SQLにおけるサブプログラムの前方宣言は、次のように単純に無視することで移行します。

PROCEDURE MYPROC( A NUMBER );
1   2  次のページ

資料紹介

■『PostgreSQL Documentation』
http://www.postgresql.org/docs/

■『PostgreSQL日本語ドキュメント』
http://www.postgresql.jp/document/

■株式会社ランス小野哲、藤本亮著『現場で使えるSQL』翔泳社

■石井達夫、山田精一ほか著『PostgreSQL構築・運用ガイド』日経BP社
書籍紹介
まるごと PostgreSQL! Vol.1
まるごと PostgreSQL! Vol.1 日本での市場シェアNo.1(オープンソースRDBMS部門)データベースソフトPostgreSQLの最新情報を、開発メンバーを含む豪華執筆陣が多面的かつ詳細に解説します。PostgreSQL用クラスタリング/レプリケーションソフト、PostgreSQL⇔Oracle移行、PostgreSQLによる大規模サイト構築法、新バージョンPostgreSQL 8.0先行レビュー、PostgreSQL用.NETデータプロバイダ等々、他では読めない貴重な記事が満載です。

発売日:2004/12/08発売
定価:\1,890(本体 \1,800+税)
奥畑 裕樹(OKUHATA, Hiroki)
著者プロフィール
奥畑 裕樹(OKUHATA, Hiroki)
Javaとオープンソース技術を得意とする技術コンサルタント。最近のテーマは、ソフトウェア開発の全体最適をはかること。気が付けば、10才のときにプログラミングを始めて以来、常に何かを作っている…。


INDEX
第13回:まとめ
例外処理
  ネストしたサブプログラム