CHAIN と SELECT INTO
平均的な RPG 開発者なら、新しいプログラミングに従事している場合に、RPG データベース命令コードを SQL における同等のコードと置き換える作業はすぐに熟練できるようになります。自分の主張を証明するため、このシリーズの掲載ごとにある命令コードまたは命令コードのセットについてお話ししましょう。今日最初に説明するのは CHAIN です。
CHAIN 命令コードは System/3 Model 6 や Model 10 ディスクの時代から覚えています。(そうです、ずっとはるか昔からやっているのです。)それ以降、あらゆる RPG プログラマーに幅広く使用されてきました。これはランダム・アクセス用の基本的な命令コードです。「当時」、キーはもちろんのこと、相対レコード番号でディスク・レコードにアクセスする際に幅広く使用されていました。おそらく今はもう使用されていないでしょう。CHAIN によるキー順ディスク・アクセスのメリットと、 SQL における同等の SELECT INTO のメリットについてお話ししましょう。
パート 1:ファイル定義
SQL ではなく、RPG で明示的にファイルを定義する必要があります。事実、各 SQL SELECT INTO は、自らのロック・パラメーターと分離パラメーターを指定できます。これについては、SELECT ステートメントの節で簡単に確認します。CHAIN(N) と UNLOCK も使用している場合、ロックに関する限り、これはプラスマイナスゼロです。
パート 2:データ定義
サブプロシージャーは、最大 256 文字の可変長ストリングを返します。これは十分すぎるほど大きいはずです。
デバッグ時に eval コマンド 1 つでレコード全体を確認できるよう、私は常に外部データ構造を持つ正規化レコードを定義します。しかしこれは RPG では必要なく、SQL で行のデータに都合よくアクセスする場合のみ必要になります。そうでない場合、各列を個別に指定する必要があります。大幅な結合があるビューまたは論理ファイルでは極めて可能性が高い 1000 の行列がある場合、必要な列のみ指定すると、パフォーマンスが向上する場合があります。列が 1 ダースほど越える場合は、時間がもったいないのでデータ構造を使用します。そうしたビューまたは論理ファイルで、多数の CHAIN や SELECT を節約することができます。我々の中で論理的なうるさ型は、これは RPG ではなく SQL の要件であると意見を戦わせると思いますが、入出力のデバッグを必要としない、意味のあるプログラムなどないと考えています。したがって、データ構造も RPG での要件になります。パート 2 は、反対者の間での押し (賭け用語における「引き分け」) です。
パート 3:レコードまたは行へのアクセス
話の核心になりました。よろしければ、行 124 の CHAIN ステートメントを、行 127 に記述している SELECT INTO ステートメントと比較してください。SELECT の方が複雑なのは明らかで、慣れていない人には多少の学習が必要です。ここで、この SELECT ステートメントでできるのと同じことを達成するのに、CHAIN で必要な労力も考慮してください。各行を以下のように考えてみます。
キーワード | パラメーター | 観察内容 |
---|---|---|
select | * |
「SELECT *」は、表またはビューのすべての列を読み取ります。コンマで区切られた個々のフィ ールドを、ただ簡単に指定できます。例を挙げます。「select vendno, vendname」があるとし ます。これは RPG に非常によく似ています。デフォルトでは、すべてのフィールドを読み取り、 サブセットを読み取る場合は、入力レコード・フィールドを指定する必要があります。 |
into | :vendds | (ご使用の RPG プログラムに参照可能な) ホスト・プログラム変数は、先頭にコロンを付加 することで SQL 変数/列と区別されます。これは、その結果のデータ構造を持つ命令コードに似 ています。フィールドをいくつかトランザクション・レコードに配置するためにマスター・レコ ードにアクセスしていて、唯一キーを指定したマスター・ファイルの行が存在する場合のみ、 「select vendname into :transvname where vendno = :transvno」を実行できます。 |
from | VENDFILE |
通常は IBM i オブジェクトの命名体系を使用します。これは *LIBL/VENDFILE と見なされます。 LIBRARY/FILE も指定できます。また、LIBRARY.FILE にピリオドを追加して、SQL 命名体系を 選ぶこともできます。 |
where | vendno = :vendno |
これはキー・リスト、CHAIN の例では、キー・パラメーターです。多少のキー入力がありますが、 学習する労力はまったくありません。繰り返しますが、where 節は非常に強力で、CHAIN の後に 続く多くの IF ステートメントを置き換えるケースが多いです。例えば、多くの種類のベンダーが あり、タイプ 'A' についてのみトランザクション・フィールドを追加したいとします。その場合 「select vendname into :transvname where vendno = :transvno and vendtype = 'A'」と指定 します。SQL select は、適切な索引がなくても、表の行を走査して機能するという点も付け加えて おきます。 |
with | NC |
これは、コミット制御なし、またロックなしを意味します。これはデフォルト動作ですが、並行アク セスが問題の場合に求めるものではない可能性があります (非コミット行を読み取りたくない場合が あります)。各 SQL ステートメントには、自身のロック・パラメーターと分離パラメーターがありま す。排他ロックを希望する場合、「with RR use and keep exclusive locks」とコーディングしま す。UPDATE、DELETE、または INSERT に続いて、 COMMIT または ROLLBACK を発行する必要 があります。いずれにしてもコミットメント制御を使おうではありませんか。この節を省略すると、 デフォルトで SQL ステートメントがコミットメント制御と先に設定した分離レベルになります。 |
fetch | first row only |
重複のための CHAIN の動作との互換性に向けて、この節を常に含めます。fetch first row only 節が なく、複数の行が select を満たす場合、SQL は、複数の行が戻されたというエラー、 SQLSTATE = '21000' または SQLCODE = -811 を返し、予想外の変数の割り当てが発生します。 正しい行が最初に選択された行になるよう、order by 節が必要な場合があります。 |
パート 4:例外処理
単刀直入な found または not found 条件について、実際に選択肢があるでしょうか。SQLCODE は、 row found および all data transfer successful 以外の条件について、ゼロ以外になります。しかし SQL により、プログラマーは上記のように幅広い警告にアクセスできるようになります。
例外処理については別の日に取り上げます。RPG リファレンス・マニュアルの場合と同様、SQL リファレンス・マニュアルおよび SQL メッセージとコード・マニュアルに習熟するのに代替手段はありません。それらはすべてオンラインで入手できます。
CHAIN を SELECT INTO と置き換える
私は、自分の例を生成してテストするのに便利な IBM i を使用しました。最新の Technology Refresh レベルの V7R1 で、私の例のコードは完全にフリー・フォーマットです。まだ V7R1 または完全フリー・フォーマットにアクセスできなくても、あらゆる RPG プログラマーが、これらの例を理解できると信じています。 一般的な CHAIN を置き換える方法を学習するのは極めて簡単です (分離は例外です。これはコンテキストによっては簡単ではありません)。思い切って提案しますが、最初の 20 件の SELECT 内に、相当な数のプログラマーは、それを手中に収めるでしょう。
Chuck Luttor : カナダ、トロントおよびオンタリオ州南部で長年、IBM i space において RPGILE および SQL のプログラミング・コンサルタント活動を実施。証券会社の会計および一般会計について幅広い知識があります。彼の顧客にはカナダの大手銀行および証券会社も含まれています。主に関心がある分野は、DDS 定義データベースから IBM i 上で RPG を使用してアクセスする SQL データ定義言語定義データベースへのマイグレーションです。
SQLすべきか否か?それが問題だ。今日のRPGプログラマーが抱える問題。
Chuck Luttor 著
SQL は 1980 年代以降のリレーショナル・データベース管理およびプラットフォーム間でのアクセスの標準でした。また、ほぼ 20 年間にわたり IBM i のために尽力してきました。しかし、まだ多数の IBM i ショップが SQL を使用していません。DB2/400 は元々 DDS でリリースされ、2000 年代初頭まで SQL が IBM i で優れたパフォーマンスを発揮して来なかったことが原因です。
過去 15 年間、IBM は IBM i ベースの SQL に多大な投資をしてきており、データベースのあらゆる新たな進歩を SQL に組み込んでいます。最近、わずかな例外はあるものの、IBM i のほぼすべてのデータベース機能強化は SQL に対して行われ、DDS は 2000 年以降機能強化していない、という Frank Soltis の発言を耳にしました。私はそれを信じます。
それに加えて、IBM は何年も前に DDS から SQL データ定義言語ステートメントを生成するために、 Generate Data Definition Language (QSQGNDDL) API を提供しました。これを簡単に行うための多数の無償ツールがあります。
なのに、なぜ多くのショップがいまだに DDS を使用しているのでしょうか。結局のところ、IBM が SQL for i に組み込んできたこの 15年にわたるデータベースの進歩を見逃してきたとしたら、IBM i 開発者である我々はどのように堂々と顔を上げて、最善を尽くしていると言い切れるのか、ということです。今日の SQL が提供するあらゆる優れた追加機能を使用すれば、はるかに生産性が上がるはずです。
私は RPG プログラマーとして、少なくとも新しいプログラム内で DDS および RPG 両方のデータベース・アクセス命令コードを、 SQL Data Definition Language (DDL) および SQL 入出力ステートメントに置き換えることは好ましいだけでなく、必要であると考えています。しかし、それらは SQL プロジェクト内では個別の手順です。最初に何をすべきでしょうか。
既存のデータベースおよび自身の DDL 再定義は、多少のハードウェア・パフォーマンス向上にのみ役立ちます。RPG プログラムの SQL 入出力は、プログラマーの生産性アップを助けます。後者の手順が最初になります。プログラマーはハードウェアよりはるかに貴重でコストが掛かるからです。またその手順は、経営側の合意や一定の取り組み以上のものがなくても、プログラマー自身によって達成することができます。そのような低コストでハイ・リターンな IT プロジェクトが果たしていくつあるのでしょうか。
次の手順である、DDL データベースの再定義を達成するために、既存の RPG プログラムを再コンパイルせずに達成できるよう、IBM は DB2 for i を誠意をもって整理しました。データベース管理ツールは、文書/相互参照およびプロモーション・ツールの両方を提供する「select the options」GUI を提供することで、SQL を作成してデータベース・オブジェクトを更新および再フォーマットするという退屈なジョブを自動化するために利用できます。データベース管理者はまだ必要ありません。しかし、その話はまた別の日にします。