ネストしたサブプログラム

   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の進化に、今後とも目が離せませんね。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30