暗黙の DL/I コードおよび明示的 DL/I コードは、実際の DL/I コードとは若干異なる、優れた擬似 DL/I 構文を使用することに気をつけてください。 詳細については、『#dli ディレクティブ』を参照してください。
DL/I に精通していない場合は、『DL/I の基本概念』を参照してください。
DL/I データベースへの アクセスに利用できる EGL 文は、次の表のとおりです。 この表には、各キーワードが生成する可能性のある DL/I 呼び出しの例が含まれています。 例えば、EGL add 文をコード化する場合、DL/I ISRT 呼び出しが生成されます。キーワードを含むコードの行にカーソルを置くか、またはその行を右クリックすることにより、EGL が生成する DL/I 呼び出しの不定形式のバージョンをプレビューすることができます。 ポップアップ・メニューから、「DLI 文」 > 「表示」を選択します。
with #dli{ statement } 構文を使って DL/I 呼び出しを直接コード化することもできます。 この構文によって、ご使用のプログラムがデータベースにアクセスする 方法 (EGL が I/O 文から生成したデフォルトの DL/I 呼び出しでは 十分でない場合に必要) をさらに指定できます。
次のリストは DL/I データベースをサポートしている EGL I/O 文を 示しています。
変更されたセグメントをデータベースに戻す。 まず get...forUpdate、get next...forUpdate、または get next inParent...forUpdate 文 (DL/I GHU、GHN、または GHNP 文を生成する) を使用してレコードを配置し、保持します。
いかなる場合でも、複数のデータベース・セグメントを単一のデフォルト EGL replace 文によって更新することはできません。
EGL set 文 (特に フォーム set record position の文) は、DL/I もサポートしています。 この文は入出力を行いませんが、データベース内に指定したセグメントを 効果的に配置します。 文の操作について詳しくは、『set』を参照してください。
PSBRecord パーツに 基づいて変数を宣言し、次にその変数名をプログラムの psb プロパティーに 割り当てます。EGL はそのレコードを使用して、DL/I 呼び出しの作成と検証を行うコードを生成します。
各 PCB レコード内で、ユーザーは複合プロパティー @PCB を使用して PCB のタイプと名前を定義し、場合によってはその PCB に可視のセグメント階層を定義します。 レコード・タイプの詳細については、『PCB レコード・パーツのプロパティー』および 『レコード・タイプとプロパティー』を参照してください。
最後に、定義済みレコード・パーツ PSBDataRecord に基づき、固定レコードを 宣言できます。そのレコードを使ってシステム変数 DLILib.psbData と対話することができます。このシステム変数にはランタイム PSB 名および PSB がアクセスされるアドレスの両方が含まれています。 このレコードは、PSB (実際は名前とアドレス) を別のプログラムに渡す必要がある場合、または別のプログラムから PSB を受け取る必要がある場合に役立ちます。
DL/I データベース中でアクセスしたい各セグメント・タイプは、使用しているプログラム中の DLISegment 型の相当するレコードを備えていなければなりません。
『DL/I データベース例』の、顧客データベースおよびコードの例について考えてみましょう。それぞれの顧客ごとに、預金状況、履歴、および個々のロケーションのセグメントがあります。 各ロケーションにオーダー・セグメントがあり、各オーダーに行項目セグメントがあります。 この場合、ユーザーは DLISegment 型のレコードを、顧客、預金、履歴、ロケーション、オーダー、および明細について作成します。
#dli ディレクティブがない場合は、EGL はデフォルト・セグメントの検索引数 (SSA) を作成して特定の DL/I セグメントを配置します。次の例に示すように、DLISegment レコード・パーツの hostVarQualifier プロパティーは、デフォルトの SSA で使用されるキー値を含むレコードを識別します。
Record CustomerRecordPart type DLISegment { segmentName="STSCCST", keyItem="customerNo" } 10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field ... end Record LocationRecordPart type DLISegment { segmentName="STSCLOC", keyItem="locationNo" } 10 locationNo char(6) { dliFieldName = "STQCLNO" }; //key field ... end Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" } // データベース PCB customerPCB DB_PCBRecord { @PCB { pcbType = DB, pcbName = "STDCDBL", hierarchy = [ @Relationship { segmentRecord = "CustomerRecordPart" }, @Relationship { segmentRecord = "LocationRecordPart", parentRecord="CustomerRecordPart" }, ...]}}; end
Program myProgram { @DLI{ psb = "myCustomerPSB" }} //変数を定義する myCustomerPSB CustomerPSBRecordPart; myCustomer CustomerRecordPart; myLocation LocationRecordPart;
get myLocation;
GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo) STSCLOC (STQCLNO = :myLocation.locationNo)
EGL は変数 myLocation をセグメント STSCLOC と正しく関連付けましたが、myCustomer 変数を見つけることができなかったことに気をつけてください。EGL は、myLocation が CustomerRecordPart を 親セグメントに持つ LocationRecordPart タイプであり、CustomerRecordPart の keyItem は customerNo であるということのみを 知っていました。
Record CustomerRecordPart type DLISegment { segmentName="STSCCST", hostVarQualifier="myCustomer", keyItem="customerNo" }
GU STSCCST (STQCCNO = :myCustomer.customerNo) STSCLOC (STQCLNO = :myLocation.locationNo)
プロパティー hostVarQualifier を使用して、データベースのセグメントに基づかないレコードのフィールドを参照することもできます。 例えば、EGL で基本レコード (トランザクション・レコードなど) 中の顧客セグメントのキー値を見つけたい場合は、そのレコード名を hostVarQualifier プロパティーに割り当てます。
相当するデータベース・セグメント・フィールドの名前と一致しない DLISegment レコード・フィールドを操作している場合は、レコード・フィールド・プロパティー dliFieldName をセグメント・フィールドの名前に設定します。
CICS では psbName で識別された PSB の スケジュールを立てることができます。スケジューリングは、 コミットによって psbRef が消去された後で発生します。 この機能を使用するには、psbRef を 0 に設定します。
Record CustomerRecordPart type DLISegment { segmentName="STSCCST", keyItem="customerNo" } 10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field 10 customerName char(25) { dliFieldName = "STUCCNM" }; 10 customerAddr1 char(25) { dliFieldName = "STQCCA1" }; 10 customerAddr2 char(25) { dliFieldName = "STQCCA2" }; 10 customerAddr3 char(25) { dliFieldName = "STQCCA3" }; end
このデータベース例の完全なレコード・レイアウトについては、『DL/I データベース例』を参照してください。
このようなレコード宣言ではデータベース・セグメントの構造を、このプログラムに見えるように記述します。 実行時に、ランタイム PCB は個々のプログラムに見えるものを決めます。
レコード内の構造は、 DL/I がそれをプログラムに表示するときに、セグメントの構造に一致する必要があります。DL/I セグメント中にあるのと同じレコード長と位置を持つ keyItem および lengthItem フィールドを定義します。 セグメントが論理子である場合は、交差データと目標親の連結キーが構造に含まれている必要があります。 セグメントが論理データベースの連結セグメントである場合は、構造に連結キー、交差データ、および目的親セグメントが含まれている必要があります。
DL/I データベースは階層型であるため、プログラムはデータベース中の現在のロケーションを把握しておく必要があります。 特定の子セグメントを配置する場合は、その子 (ある場合) の親セグメント、その親 (ある場合) の親セグメント、というように、データベースのルートまで遡って指定する必要があります。
//レコードのインスタンスを作成する myCustomer CustomerRecordPart; myLocation LocationRecordPart; myOrder OrderRecordPart; myItem ItemRecordPart; //セグメント検索引数を作成する myCustomer.customerNo = "5001"; myLocation.locationNo = "22"; myOrder.orderDateNo = "20050730A003"; myItem.itemInventoryNo = "CHAIR"; //1st part compound key myItem.itemLineNo = 27; //項目を入手し、保持する try get myItem forUpdate; onException myErrorHandler(2); end
実行時に、DL/I は顧客用キー・フィールド (6 バイト)、ロケーション用 (6 バイト)、注文用 (12 バイト)、項目用 (6 + 2 バイト) を含む、30 バイトの連結セグメントの検索引数により、GU (get unique) 呼び出しを行います。