|
|
前のページ 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)
Javaとオープンソース技術を得意とする技術コンサルタント。最近のテーマは、ソフトウェア開発の全体最適をはかること。気が付けば、10才のときにプログラミングを始めて以来、常に何かを作っている…。
|
|
|
|