NEWS
押さえておきたい!RPGの新機能 押さえておきたい!RPGの新機能
2021.04.08

【第25回】RPGをストアドプロシージャとして再利用する

【第25回】RPGをストアドプロシージャとして再利用する

投稿日:2021年4月8日

外部システムからIBM iのビジネスロジックにアクセスさせる方法の1つとして、既存のRPGロジックを利用してストアドプロシージャ化し、外部システムからSQLリクエストでこれを呼び出すことが考えられます。本記事は、その方法について簡潔に説明しており、外部システムとIBM iの連携処理を考えている方に大いに参考になるものと思われます。
(以上編集部注)

本記事では、RPGプログラムをストアドプロシージャに変えるための基本事項を概説します。

03/21/2012 ジョン・パリス

今日のIT部門では、複数のプラットフォームを横断してアプリケーションを統合するのが一般的です。大量のビジネス処理を行うアプリケーションがRPGで書かれているとしても、非RPGかつ非IBMアプリケーションからその幾つかのビジネス機能にアクセスするという要求が多分あるでしょう。そのアクセスを提供する最も効率の良い方法の1つは、あらゆるSQLプラットフォームから呼び出せるストアドプロシージャを提供することです。幸いなことに、それは実行時に効率的なだけでなく、そうすることがとても容易です。この記事では、RPGプログラムをストアドプロシージャに変えるための基礎についてちょっと見てみようと思います。

ストアドプロシージャはSQLから呼び出せるプログラムに過ぎません。SQLはデータベース言語なので、私たちにとってその呼び出しはDB2経由でシステムに入ってくることを意味します。IBM iには外部及びSQLという2種類のストアドプロシージャがあります。SQLストアドプロシージャは完全にSQLプロシージャ言語で書かれているのに対し、外部ストアドプロシージャはRPGのような高水準言語で書かれています。外部ストアドプロシージャは、既存ロジックの幾つかを再利用する、あるいは新しい言語やプログラミング技法を覚えることなく、これら他のタイプのアプリケーションのために幾らかのロジックを書くことで、RPGスキルを活用するための良い方法を提供してくれるので、ここでは外部ストアドプロシージャに集中します。渡されたパラメータを介して情報をやり取りするRPG(またはCOBOLないしCL)プログラムが書けるならば、ストアドプロシージャを書くことができます。

ストアドプロシージャはSQLを使って呼び出されるとはいえ、(結果セットを返すといった、より高度なストアドプロシージャを使おうと決めたなら別ですが)呼び出されるRPGプログラムがSQLを使用する必要はありません。もちろん埋め込みSQLを使うこともできますが、RPGに“元々備わっている” CHAIN, READ, UPDATE命令を使うこともできます。

ストアドプロシージャの作成

呼び出し元と呼び出し先の間で情報のやり取りをするために伝統的スタイルのパラメータを使った簡単なストアドプロシージャを開発することにしましょう。後日の記事で、結果セットを返すといった幾つかのもっと高度なオプションを調べるつもりです。

例として、顧客番号を入力として受け入れ、顧客に関する幾つかの情報をパラメータ経由で返すプログラムがあると仮定します。そのプログラムに対するパラメータリストは下記の通りです。例ではプロシージャインターフェスを使いましたが、*ENTRY PLISTを使っても同様に動くはずです。

D CustInfo         PI
D CustNo                    5P 0
D Name                     15A
D City                      25A
D State                  2A
D Active                    1P 0

このプログラムはSQLを使って呼び出されるので、データベースにプログラムに関する情報とその呼び出し方(つまり、プログラムの存在場所と使用するパラメータ)を通知する必要があります。RPGプログラムに対して変更を加える必要は全くありません。この作業はCREATE PROCEDUREというSQL文を使って行います。以下に示したのは、顧客情報プログラムをデータベースに登録するのに使用できるSQL文の例です。


CREATE PROCEDURE GetCustInfo
 (IN CustNo DEC (5,0), OUT Name CHAR (15), OUT City CHAR(25),
 OUT St CHAR(2), OUT Act DEC(1,0))
 EXTERNAL NAME MYLIB/CUSTINFO
 LANGUAGE RPGLE
 PARAMETER STYLE GENERAL

プロシージャ名(GetCustInfo)は、呼び出し元のアプリケーションが使う名前だという事に注意してください。例えば、実際のプログラムオブジェクトの名前は(EXTERNAL NAMEパラメータで指定されたように)ライブラリMYLIBのCUSTINFOです。サービスプログラム・プロシージャも同様にストアドプロシージャとして登録できます。その場合、外部名称の構文はMYLIB/CUSTSRVPGM(CUSTINFO)のように、サービスプログラム名の後ろに括弧で囲まれたプロシージャ名を記述する形になります。

プログラムが書かれている言語をRPGLEと指定しているのは、幾つかの言語ではパラメータの渡し方の標準が異なっており、データベースはパラメータの受け渡しを適切に行う責任があるというのがその理由です。PARAMETER STYLEの指定値(この例の場合はGENERAL)は、パラメータ受け渡しの一番単純な形式を使っていることを規定しています。これは他の幾つかのパラメータスタイルでは許されるような、ヌルサポートもSQLエラーのフィードバックも含みません。

プロシージャ名の直後にある括弧内の内容は、プログラムが使用するパラメータの一覧です。この例の場合、顧客番号は入力パラメータそして残りのパラメータは出力です。もう1つのオプションはINOUTで、これはフィールドが入力と出力の両方に使われることを意味します。もちろん、RPGプログラムに関する限りすべてのパラメータは厳密にはINOUTパラメータです。しかし、呼び出し元がプログラムとどのようにインターフェースで繋がるかを理解できるよう、パラメータが論理的にどのように使われるかを規定するのは良い考えです。この例は、パラメータ名はここでは単なる文書に過ぎないという事実を示していることに気付いたかもしれません。パラメータ名はプログラムのパラメータフィールドの名前と一致する必要はありません。

パラメータのデータ型も規定されていますが、これらはSQLデータ型を使って規定されなければなりません。DEC(またはDecimal)はパック十進数に対するSQLデータ型です。CHAR(またはCharacter)についての説明は不要であることを望みます。ゾーン十進数データを渡しているならば、データ型としてNUMERICを指定することになります。

どのようにCREATE PROCEDURE文を入力するのでしょう?IBM i上で動作する他のSQL機能のためのあらゆるSQLインターフェースが使えます。(STRSQLコマンドを使って)対話型SQLは、ナビゲーターのSQL実行スクリプトと同様に使えます。またCREATE PROCEDUREコマンドをソースメンバーに入れ、それをRUNSQLSTMコマンドで実行することもできます。また、ナビゲーターにはストアドプロシージャの作成を支援するウィザードもあります。

ストアドプロシージャのテスト

ストアドプロシージャを作成し終えましたが、テストのためにどうやってそれを呼び出すことができるのでしょうか?最も簡単な1つの方法は、ナビゲーターのSQLスクリプト実行を使ってストアドプロシージャをテストすることです。このインターフェースにより、プロシージャを呼び出してパラメータを渡すことができます。呼び出した後、戻ってきたパラメータの値(OUTまたはINOUTの値)を見ることができます。また、このインターフェースはあなたが書きたいと思うかもしれない、もっと高度なプロシージャに対する結果セットの値も表示できます。

対話型SQL(STRSQL)からストアドプロシージャを呼び出すことができますが、結果を見ることができないので、この方法は多分あまりよくない選択でしょう。また、もちろんテスト目的でストアドプロシージャを呼び出すRPGプログラム(呼び出されたプログラムを試しに動かすための一種のテスト装置)を書くこともできます。ストアドプロシージャのためのテスト装置をRPGで書きたいのであれば、呼び出しには埋め込みSQLを使う必要があります。この記事の例題プロシージャに対する呼び出し文は下記のようなものになるでしょう。

Exec SQL Call GetCustInfo( :CustNo, :CusName, :CCity, :CState, :Active );

ストアドプロシージャを使う理由

この例はとても単純なので、簡単なSELECT文で容易に行えそうな何かのために、他のプラットフォーム上のアプリケーションがわざわざストアドプロシージャを呼び出す理由を訝しく思うかもしれません。ストアドプロシージャを使うと、より効率的であるかもしれないことがよくあります。とりわけ複数の表(IBM iで言うファイル)に潜在的に厳密にどの行にアクセスする必要があるかを判断するプログラムロジックを使ってアクセスする必要のある要件がある場合がそうです。もちろん、RPGはまた(多分CLとの組み合わせで)SQL文では容易に処理できないユニークな機能をも提供します。例えば、SQLでは不可能な数値編集機能(すなわち、%EditCや%EditW経由で)を提供するためにRPGを使いたいと思うかもしれません。あるいは、そのRPGプログラムは情報を返す前にバックグラウンドで重要な処理をしているかもしれません。

他のアプリケーション環境からRPGプログラムを呼び出すために、簡単なストアドプロシージャを作るのは、既存のRPGコードを再利用しかつ新しいアプリケーション環境でRPGスキルを活用するための容易で効果的な方法です。この記事で紹介したような単純なパラメータ渡しを試してみてください。この後の記事で、顧客一覧のような情報を返すといった、あなたがストアドプロシージャで採用したいと思うもっと高度なテクニックについて考察する予定です。

いいねと思ったらシェア
twitter
facebook
hatena
押さえておきたい!RPGの新機能 目次を見る

この連載は…

押さえておきたい!RPGの新機能
関連記事
【第18回】sshによるIBM iからPCプログラムの実行 ‐ セキュアなRUNRMTCMDの代替策 ‐
【第18回】sshによるIBM iからPCプログラムの実行 ‐ セキュアなRUNRMTCMDの代替策 ‐
【第20回】RPGの基礎:配列
【第20回】RPGの基礎:配列
【第19回】RPG可変長フィールド入門
【第19回】RPG可変長フィールド入門
あなたにオススメの連載
できるIBM i 温故知新編
9記事
できるIBM i 温故知新編
IBM i の”新”必須言語 〜FFRPG入門〜
14記事
IBM i の”新”必須言語 〜FFRPG入門〜
IBM i アプリの第二の柱 OSS
15記事
IBM i アプリの第二の柱 OSS
PAGE TOP