ブライアン・マイヤース著 IBMのILE RPG/400コンパイラの新しいリリースが出るたびに今度は何が変わったのかと思わずワクワクしながら探してしまいます。どんな新機能なのだろうか。今までとどこが違うのか。新しい機能はどうやって使うのだろうか。的を射た機能強化は何か。失敗といえる機能強化はないのか、などと。 V5R4も例外ではありません。V5R4の新機能は、組み込みSQLでのフリー・フォーマットのサポート、データ構造移動用の新しい命令コード、XMLドキュメントの新規サポートの3つの大きなカテゴリに分けられます。 他にも細かな改良や調整部分がありますが、上記の3つが主なものです。本稿ではそのうちの最初の2つについて述べます。XMLについてはまた別の機会に説明します。 ついにフリーになった組み込みSQL 組み込みSQLは後からの思いつきでRPGに付け加えられたものだという印象をずっと持っていました。組み込みSQLの文法は、さまざまな場で活躍しているプログラマの使い勝手を考えたものではなく、IBMのプリコンパイラの都合に合わせて設計されたのではと思わせる部分がありました。固定のフォーマットの中に/EXEC SQLや/END-EXECなどといったコンパイラへの指示語を文法に使用しなければなりませんでした。組み込みSQL文が複数行に渡る時はC+という継続行の指示を付け加えなければならず、ソースコードを読みづらいものにしていました。固定フォーマットのRPG中に組み込まれたSQLコードの一部を図1に示します。 RPG IVがフリー・フォーマット仕様をサポートし始めた当初は、RPGと組み込みSQLを組み合わせて使用するのは耐えがたいほどの苦痛でした。この両者を使用しているプログラムの中身や目的を読んで理解するのはほとんど不可能だと思いました。この両者を結婚させようとしたがために/FREEと/END-FREEの指示語が「ベビー・ブーム」のように発生したなどという話は聞きたくもありません。SQLコード部分をサブルーチンやプロシージャで分離すれば多少は良くなりますが、それによりプログラム構造の体裁が悪くなってしまうことがよくあります。フリー・フォーマットのRPGにSQLコードを無理やり組み入れた例を図2に示します。 長い間続いていたSQLの悪夢からようやく覚めることができました。V5R4で新しくサポートされるようになったフリー・フォーマットRPG IVへの組み込みSQL文は本当に洗練された機能です。固定フォーマットに戻ることなく、フリー・フォーマットのコードの中にSQL文を組み込むことができるようになりました。各SQL文はEXEC SQLというコンパイラ指示語ではじめなければいけない点は変わりがありませんが、一行の中でどこに記述してもよく、斜線記号(/)を前に書く必要もありません。SQL文の終わりには/END-EXEC指示語の代わりにセミコロン(;)を記述します。EXEC SQL指示語は一行中に記述しなければなりませんが、それ以後のSQL文は空白文字部分で分割して複数行にまたがっても構いませんし、分割する際に特別な継続行文字は不要です(ただし文字列定数を分割する際は「+」という継続文字をつける必要があります)。 V5R4で組み込みSQL文を記述した例を図3に示します。図を見ていただくとお分かりの通り、SQLとRPGがきれいに統合されています。つまり、SQL文を実行するという点を除けばEXEC SQL指示語がRPGの命令コードのように見えるのです。また、RPGで使用されていて今ではおなじみのものとなった「//」を使用したコメントの書き方もSQL文はサポートしています。コメントは「/*」と「*/」で囲んでも構いません。 上記のような嬉しい新機能についてはIBMに喝采を贈りたいのですが、2つだけちょっとした注意が必要です。1つ目は、一部のSQL文ではTAGが必要で、しかもこれはフリー・フォーマットではサポートされていないということ。2つ目は、ソースコード中でSQL文が見た目上正しく並ぶようにするには依然としてプリコンパイラが必要であるといことです。私は組み込みSQLのコードを書くときはいつも自分で「PREPARE、DECLARE、OPEN、FETCH、CLOSE」と繰り返しつぶやいています。 RPG通信講座 新しいEVAL-CORR(Assign Corresponding Subfields)命令は1つのデータ構造のサブフィールドを別のデータ構造のサブフィールドに割り当てます。個々のサブフィールドを別々の代入式で移動する必要はなく、代わりに1つの命令を書けばよいのです。EVAL-CORRを使う最大の利点は、データ構造が格納されている場所に応じてサブフィールドを割り当てるのではなく、データ構造の名前とデータ・タイプに応じて割り当てるという点です。したがってデータ構造のサブフィールドを別のデータ構造のサブフィールドに正しく割り当てるのに、EVAL-CORRに対してはこれら両者が全く同じ構造をしている必要がないということです。 EVAL-CORRがどのように動作するのかを理解するために例(図4)を見てみましょう。この例に出てくる2つのデータ構造のサブフィールドには共通した名前のものがあります。全く等価なサブフィールド、つまりデータ・タイプも長さも全く同じサブフィールドもあります。そうでないフィールドは名前やデータ・タイプ、長さが少しずつ違います。1つのデータ構造を別のデータ構造に割り当てるだけの以下のような単純なプログラム(EVALを使用することを意味している)であれば、 DS2 = DS1; となり、DS2のデータ構造の値は次のようにどうしようもないほど乱雑になってしまいます。 DS2.Account = 61938 DS2.Department = '345' DS2.Xfactor = 'Kay' DS2.Lastdate = ' Elmnop 0' DS2.Name = '000000067890122' DS2.Creditok = '0' サブフィールド間で値を直接割り当てるには、プログラムは片方のデータ構造の値をもう一方の論理的に対応するサブフィールドにそれぞれ割り当てなければなりません。 DS2.Account = DS1.Account; DS2.Lastdate = DS1.Lastdate; DS2.Name = DS1.Name; DS2.Creditok = DS1.Creditok; 割り当てた後のDS2は以下のようになります。 DS2.Account = 12345 DS2.Department = (Unaffected) DS2.Xfactor = (Unaffected) DS2.Lastdate = D'2006-01-01' DS2.Name = 'Kay Elmnopbbbbb' (bはブランクの意) DS2.Creditok = '1' V5R4でも同じような結果になるようにするためには、次のようにEVAL-CORRを使用するだけです。 Eval-corr DS2 = DS1; 値を移動するのにサブフィールドが同じ場所にある必要はありません。EVAL-CORRは同じ名前で互換性のあるサブフィールドを移動させていますが、この時データ・タイプと長さは全く同じである必要はないという点に注意してください。上述の例では、サブフィールドDS1.Accountは符号付数値フィールドであるのに対してDS2.Accountは整数になっています。DS1.Nameは10バイトですがDS2.Nameは15バイトです。DS1.CreditokはインジケータですがDS2.CreditOKは1バイトの文字フィールドです。EVAL-CORRはこれら全てのフィールドを正しく割り当てます。 つまり、組み込み機能を使わずにEVALを使用してサブフィールドのデータを割り当てることができるのであれば、EVAL-CORRはそのサブフィールドのデータをうまく移動させることができるというわけです。 DS1.XfactorとDS2.Xfactorには互換性はありませんので値を移動することはできません。Ytdsalesは移動先のデータ構造DS2には存在しませんので無視されます。Departmentは移動元のデータ構造DS1には存在しませんので移動に関しては影響ありません。 コンパイラ・リストにある新しい「EVAL-CORRのサマリ」セクションには、移動対象のフィールドと対象でないフィールドが記載されています。また移動の影響を受ける可能性のあるサブフィールド間の差異がわかるようになっています。 EVAL-CORRに影響を与えるような特殊な状況は多数ありますが、最も一般的なものは以下のとおりです。 QUALIFIEDのデータ構造が1つ以上あること。 EVAL-CORRは単純なデータ構造だけでなく、LIKEDSやLIKEREC、外部記述のデータ構造とも動作する。 EVAL-CORRは内部フィールド名を使用してどのサブフィールドが移動するかを判断するので、PREFIXキーワードなどはEVAL-CORRの操作に影響する。 (H)エクステンダーでEVAL-CORRを使用すると数値の代入は四捨五入される。 移動元フィールドと移動先フィールドがともにヌル値可能フィールドである場合、EVAL-CORRは移動先のヌル値インジケータをセットして移動元側と一致させる。移動先フィールドがヌル値可能フィールドでも移動元がヌル値可能フィールドではない場合は、移動先側のヌル値インジケータはOFFになる。 EVAL-CORRは拡張Factor 2を使用して固定フォーマットで動作するが、固定フォーマット中では(H)、(M)、(R)のエクステンダーを使用することはできない。 EVAL-CORRを使用すると、外部記述されたファイルやレコード・フォーマットを使用するファイルI/O操作用の結果データ構造の利用が容易になります。レイアウト間の差異があまりないときは、EVAL-CORRを使用してフォーマット間でデータを簡単に移行できます。また、データベースのレコードをプログラム中に読み込んでディスプレイ・ファイル・フォーマットで使用する場合もEVAL-CORRを使用したほうが楽です。 2つのデータ構造のサブフィールド名が全く同じではないにしても似たような名前であれば、V5R4で機能強化されたPREFIXキーワードを利用できるかもしれません。今回の機能強化によりフィールド名の始めの文字を取り除くことができるようになりました。データ構造内のサブフィールドのプレフィックスとして空白文字リテラルを使用した場合、PREFIXによりサブフィールド名中の指定した文字数だけ文字が取り除かれます。たとえば、外部記述されたデータ構造に対して次のようなキーワードを使用して、そのデータ構造中にあるサブフィールド名の最初の2文字を取り除くことができます。 PREFIX(':2) EVAL-CORRは内部サブフィールド名(つまり最初の2文字がない)を使用します。 その他の機能強化は? SQL文をフリー・フォーマットのコード中に組み込むことが可能になったことで、プログラマがフリー・フォーマットのRPGを使用することの妨げになっていた最後の障害の1つが取り除かれたことには間違いありません。EVAL-CORRの必要性は長年にわたって問題となっていました。ところでIBMはV5R4で他に何をRPG IVに追加したのでしょうか。 前述以外の主な機能強化はXMLドキュメントの直接サポートに関するものです。XMLはeコマースの「共通語」と呼ばれることもあります。XMLドキュメントはHTMLドキュメントと似ていますが、テキストデータではなくフォーマット化されたデータを含むことを重視しています。XML文書はインターネット上でのデータの共有を促進します。XMLはドキュメント内でデータを記述するためのWeb標準でありますが、固有の目的に応じてカスタマイズすることもできます。 XML-SAXとXML-INTOという新しい命令コードを使用すると、RPGがXMLドキュメントの個々の要素をプロシージャや変数に渡しながらドキュメントを読むことができるようになります。これらの命令コードは新しい2つの関数と組み合わせて使用します。1つは%XMLで処理対象のXMLドキュメントを識別し、もう1つは%HANDLERでドキュメントの要素を処理するプロシージャを指名します。 RPGほどすばやく目立って変化し現在の環境に迅速に対応しているコンピュータ言語はありません。私はもう次のリリースが待ち遠しくてなりません。 ブライアン・マイヤース氏はベル・データ鰍フ業務提携先、米Penton Media, Inc.が発行する月刊誌「iSeries NEWS」のテクニカル・エディタです。