TOP書籍連動> ネストしたサブプログラム
まるごと PostgreSQL!
PostgreSQLとOracleによるデータベース相互移行マニュアル

第13回:まとめ
著者:奥畑 裕樹(OKUHATA, Hiroki)   2006/1/6
前のページ  1  2
ネストしたサブプログラム

   PL/SQLでは、ブロック内に別のサブプログラムを宣言できます(リスト27)。

DECLARE
  A NUMBER DEFAULT 1;
  PROCEDURE MYPROC(B NUMBER) IS
    BEGIN
      A := A + B;
    END MYPROC;
BEGIN
  DBMS_OUTPUT.PUT_LINE( 'A = ' || A );
  MYPROC( 3 );
  DBMS_OUTPUT.PUT_LINE( 'A = ' || A );
END;

リスト29:PL/SQLでのサブプログラム宣言

   PostgreSQLには同等の機能がないので、まずブロック内のサブプログラムを別の関数にします。そのうえで、ブロック内の変数への参照があったときは、その変数の受け渡しと結果の受け取り処理を追加します(リスト28)。

CREATE FUNCTION MYPROC(INTEGER,INTEGER)
RETURNS INTEGER AS '
  DECLARE
    A ALIAS FOR $1;
    B ALIAS FOR $2;
    C INTEGER;
  BEGIN
    C := A + B;
    RETURN C;
  END;
 CREATE FUNCTION TEST_MYPROC()

   RETURNS VOID AS '
 DECLARE
   A INTEGER DEFAULT 1;
 BEGIN
   RAISE INFO ''A = %'', A;
   A := MYPROC( A, 3 );
   RAISE INFO ''A = %'', A;
RETURN;
   END;
 ' LANGUAGE 'plpgsql';

リスト30:変数の受け渡しと結果の受け取り処理

   次がその実行結果です。

% SELECT TEST_MYPROC();

 INFO: A = 1
 INFO: A = 4
パッケージ

   PL/SQLでは、パッケージを使って型やサブプログラムをまとめることができます(リスト29)。つまり、名前空間の管理をすることができますが、PostgreSQLにはパッケージのしくみはありません。

-- パッケージ仕様
CREATE PACKAGE MY_PKG AS
  CURSOR C1 RETURN 顧客マスタ%ROWTYPE;
  FUNCTION GET_ONE RETURN NUMBER;
END MY_PKG;

-- パッケージ実装
CREATE OR REPLACE PACKAGE BODY MY_PKG AS
  CURSOR C1 RETURN 顧客マスタ%ROWTYPE IS
   SELECT * FROM 顧客マスタ;
  FUNCTION GET_ONE RETURN NUMBER IS
    BEGIN
      RETURN 1;
    END GET_ONE;
END MY_PKG;

リスト31:PL/SQLでのパッケージ実装例

   図18はリスト31の実行結果です。

DECLARE
  customer 顧客マスタ%ROWTYPE;
BEGIN
  OPEN MY_PKG.C1;
  LOOP
    FETCH MY_PKG.C1 INTO customer;
    EXIT WHEN MY_PKG.C1%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(
      '顧客= ' || customer.顧客名);
  END LOOP;
  CLOSE MY_PKG.C1;
END;

顧客= (株)ワイキキソフト
顧客= 鈴木商事
顧客= 斎藤模型店
顧客= マクロハード
顧客= (株)ランヌ

図18:リスト31の実行結果

   代わりに、PostgreSQLではスキーマを使って名前空間の管理をすることができます。しかし、スキーマにはデータオブジェクトを登録することができないので少々工夫が必要です(リスト30)。

CREATE SCHEMA MY_PKG;

CREATE OR REPLACE FUNCTION
  MY_PKG.C1(refcursor)
RETURNS refcursor AS '
  BEGIN
    OPEN $1 FOR SELECT * FROM 顧客マスタ;
    RETURN $1;
  END;
' LANGUAGE 'plpgsql';

CREATE FUNCTION MY_PKG.GET_ONE()
RETURNS INTEGER AS '
    BEGIN
      RETURN 1;
    END;
' LANGUAGE 'plpgsql';

リスト32:PostgreSQLでの名前空間の管理

   図19は、その実行結果です。

CREATE OR REPLACE FUNCTION TEST_MYPKG()
RETURNS VOID AS '
DECLARE
  C1 refcursor;
  customer 顧客マスタ%ROWTYPE;
BEGIN
  C1 := MY_PKG.C1(''C1'');
  LOOP
    FETCH C1 INTO customer;
    EXIT WHEN NOT FOUND;
    RAISE INFO ''顧客= %'', customer.顧客名;
  END LOOP;
  CLOSE C1;
  RETURN;
END;
' LANGUAGE 'plpgsql';

SELECT TEST_MYPKG();

INFO: 顧客= (株)ワイキキソフト
INFO: 顧客= 鈴木商事
INFO: 顧客= 斎藤模型店
INFO: 顧客= マクロハード
INFO: 顧客= (株)ランヌ

図19:リスト32の実行結果


ライブラリ

   PostgreSQLにはOracleにあるような膨大なライブラリが存在しません。そのため、必要なライブラリに相当する機能を、PostgreSQLのユーザー定義関数などを使って実装する必要があります。

   興味のある方は、PL/Perlなどを用いて次のようなパッケージの自作に挑戦してみるとよいでしょう。

  • DBMS_OUTPUT
  • UTL_FILE
  • UTL_HTTP
まとめ

   いかがでしたでしょうか。

   やはり機能が少ない分、OracleからPostgreSQLに移行する方が苦労すると思います。ですが、いろいろと工夫すれば意外に多くの機能を移行できると思われたのではないでしょうか。

   PostgreSQLは活発に開発が続けられており、商用データベースの高度な機能も、どんどん実装されています。注目の8.0(本稿執筆時点でベータ版)では、「Point In Time Recovery」やセーブポイントなどに対応します。

   バージョンを重ねるにつれ、相互移行の苦労はどんどん減っていくと思います。PostgreSQLの進化に、今後とも目が離せませんね。

前のページ  1  2


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


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