デフォルトの get next ステートメントは、データベースの現在位置で開始し、すべての親の下にあるターゲット・セグメントの次のオカレンスについてデータベース全体を検索します。 検索の範囲を、現時点で確立されている従属チェーンに限定するには 、get next inParent ステートメントを使用します。
get myOrder with #dli {
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STSOCORD (STQCODN = :myOrder.orderDateno) };
get next inParent myItem;
while (myItem not noRecordFound)
// process the current item
get next inParent myItem;
end
GNP STLCITM
targetBalance decimal(12,2);
targetBalance = 10,000.00;
get next myCustomer,myCrStatus with #dli{
GU STSCCST*D STSCSTA (STFCSBL >= :targetBalance) };
Record CustomerData type basicRecord
10 customerNo char(6)
...
end
Program myProgram
(customerParm CustomerData)
{ @DLI{ psb = "myCustomerPSB" }}
//declare variables
myCustomerPSB CustomerPSBRecordPart;
myCustomer CustomerRecordPart;
myCustomer.customerNo = CustomerParm.customerNo;
get myCustomer;
GU STSCCST (STQCCNO = :myCustomer.customerNo)
この方法の長所は、大変シンプルである点です。
欠点は、カスタマー番号をセグメント・レコードに移動するというパフォーマンス上の
オーバーヘッドがわずかに発生する点です。get myCustomer with #dli {
GU STSCCST (STQCCNO = :customerParm.customerNo) } ;
この方法では、
カスタマー番号を移動するというパフォーマンス上のオーバーヘッドが発生しません。
ただし、デフォルトの #dli ディレクティブに貼り付けてから、パラメーター・レコードに合わせて
正しいレコード変数名を使用するようにコードを変更するのに、やや時間がかかります。Record CustomerRecordPart type DLISegment
{segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier="customerParm" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
get myCustomer;
GU STSCCST (STQCCNO = :customerParm.customerNo)
この方法の長所は、#dli ディレクティブ用にコード化したものと同じ疑似 DL/I コードが得られ、実際に #dli ディレクティブをコード化する必要がない点です。欠点は、EGL が、CustomerRecordPart を使用する 暗黙的 DL/I データベース I/O ステートメントごとに、customerParm を修飾子として使用するようになる点です。
暗黙的 DL/I データベース I/O を使用して、非ルート・セグメントを検索できます。 EGL は、PCB でのターゲット・セグメントの階層ポジションに基づいて、SSA のチェーン全体を作成します。 ただし、階層のより高いレベルにあるセグメントについては、EGL は、プログラム変数の名前を自動的に決定してセグメントの修飾子として使用することはできません。
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
get myLocation;
EGL は、以下の疑似 DL/I コードを作成します。GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
EGL は変数 myLocation をセグメント STSCLOC に正しく関連付けているものの、一方で EGL は、CustomerRecordPart に基づいている変数 myCustomer を検出できなかった点に注意してください。 EGL が認識しているのは、myLocation のタイプが LocationRecordPart であり、その親セグメントは CustomerRecordPart であること、 また CustomerRecordPart の keyItem は customerNo であることのみです。
CustomerRecordPart CustomerRecordPart;
次のように、EGL は同じ
疑似 DL/I コードを作成します。GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
EGL は、PCB 階層情報からデフォルトの SSA を作成するので、この方法で簡単に、EGL が使用する変数名をご使用のプログラムのレコード変数宣言と必ず 一致させることができます。 欠点として、この手法は、パーツおよび変数に別の名前を使用するという、一般的な慣例に従わない点があります。
get myLocation with #dli {
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
この手法の長所は、使用されているホスト変数が大変わかりやすい点です。 ホスト変数修飾子またはフィールド名が、DL/I セグメント・レコードに基づくレコード変数と異なる場合には、簡単に使用できる手法です。 欠点は、すべての明示的 I/O の場合と同様です。つまり、階層またはキー・フィールドが変更されても、明示的 DL/I データベース I/O ステートメントは、自動的に変更されません。
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier = "myCustomer" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
ここで、以下の get ステートメントを使用する場合:get myLocation;
EGL は、以下の正しい
疑似 DL/I コードを生成します。GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
この手法の長所は、暗黙的 DL/I データベース I/O を使用できることと、レコード変数および DL/I セグメント・レコードに別の名前を指定することができる点です。 欠点は、EGL が、CustomerRecordPart を使用する暗黙的 DL/I データベース I/O ステートメントごとに、myCustomer を修飾子として使用するようになる点です。
// database PCB for customer by Name
customerNamePCB DB_PCBRecord
{ @PCB { pcbType = DB, pcbName = "STDCNAM",
secondaryIndex = "STUCCNM",
hierarchy = [ @relationship { segmentRecord = "CustomerRecordPart" },
... ] }
}
pcbName プロパティーは、ランタイム PSB の実際 の DL/I データベース PCB と一致させる必要があります。 secondaryIndex プロパティーには、データベース管理者 が、ランタイム PCB の XDFLD ステートメントで指定するフィールド名と同じものを指定する必要があります。ここで、階層に CustomerRecordPart を含む PSB レコードには 、2 つの PCB レコードが存在します。
myCustomer CustomerRecordPart;
get myCustomer;
EGL は、CustomerRecord パーツを含む PSB レコードの最初の PCB レコードに基づいて、疑似 DL/I コードを作成します。get myCustomer usingPCB customerNamePCB;
EGL は、以下の疑似 DL/I コードを作成します。GU STSCCST (STUCCNM = :myCustomer.customerName)
// orders view of customer database
ordersByReferencePCB DB_PCBRecord
{ @PCB { pcbType = DB, pcbName = "STDCDBL",
secondaryIndex = "STFCORF", //use DL/I name
hierarchy = [
@relationship { segmentRecord = "OrderRecordPart" },
@relationship { segmentRecord = "LocationRecordPart",
parentRecord = "OrderRecordPart" },
@relationship { segmentRecord = "CustomerRecordPart",
parentRecord = "LocationRecordPart" },
@relationship { segmentRecord = "ItemRecordPart",
parentRecord = "OrderRecordPart" }
]}
};
end
get myOrder, myCustomer with #dli{
GU STPCORD*D (STQCODN = :myOrder.orderReference)
STSCLOC
STSCCST };
get myCustomer, myLocation, myOrder;
このステートメントは、以下の DL/I 疑似コードを生成します。GU STSCCST*D (STQCCNO = :myCustomer.customerNo)
STSCLOC*D (STQCLNO = :myLocation.locationNo)
STPCORD (STQCDDN = :myOrder.orderDateNo)
get myCustomer, myLocation, myOrder forUpdate;
replace myOrder with #dli{
REPL STSCCST*N
STSCLOC*N
STPCORD };
D コマンド・コードを指定した get forUpdate ステートメントに従う delete 関数に対するデフォルトの DL/I 呼び出し EGL ビルドは、検索される各セグメントを削除しません。
delete ステートメントで指定されたターゲット・セグメントのみを削除します。myHistory HistoryRecordPart
redefCustomer CustomerRecordPart {redefines=myHistory};
redefLocation LocationRecordPart {redefines=myHistory};
...
//read next segment, whatever type it is, into history record
while (myHistory not EOF)
get next myHistory with #dli{
GN };
//so what type was it?
case (dliVar.segmentName)
when "STSCCST" // it was a customer
printCustomer();
when "STSCLOC" // it was a location
printLocation();
...
end
end
get ステートメント および get next ステートメントを使用して 、動的配列に対して DL/I セグメントを検索できます。配列 そのもの (配列のメンバーについてのみ) にキー・フィールドはないので、いくつかの特殊な手法 を使用して、EGL が正しいコードを作成できるようにする必要があります。
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20}; // オーダーの配列
myCustomer.customerNo = "123456";
myLocation.locationNo = "ABCDEF";
myOrderDateNo = "20050730A003";
get myOrderArray; // 最初に配列を埋める
... do some processing
get next myOrderArray; // 20 オーダーの次のバッチを取得する
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :LocationRecordPart.locationNo)
STPCORD (STQCODN = :OrderRecordPart.orderDateNo)
GN STPCORD };
get next myOrderArray with #dli{
GN STPCORD };
20 オーダーの最初のバッチに対する動的配列を get ステートメントによって埋めるには、初回の GU 呼び出しを行った後で、配列がフルになるか、 または DL/I がセグメント・オカレンスをすべて検索するまで、GN 呼び出しをループさせる必要があります。 EGL が作成する疑似 DL/I コードで、GU 呼び出しは、最初のオーダー・セグメントを検索します。 EGL は、GN 呼び出しをループとして扱い、配列がフルになるか、DL/I がセグメント・オカレンスをすべて検索するまで、ループするロジックを提供します。 同様に、EGL は get next ステートメントをループとして扱い、 ループ制御ロジックをユーザーに提供します。
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
この関数を、次のように変更します。Record STSCCST type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" }
// database PCB
customerPCB DB_PCBRecord { @PCB { pcbType = DB, pcbName = "STDCDBL",
hierarchy = [ @relationship { segmentRecord = "STSCCST" },
@relationship {segmentRecord="STSCLOC",
parentRecord="STSCCST"},
@relationship {segmentRecord="STPCORD",
parentRecord="STSCLOC"}
]}};
end
STSCCST STSCCST;
STSCLOC STSCLOC;
STPCORD STPCORD;
myOrderArray STPCORD [] {maxsize = 20}; // array of orders
get myOrderArray; // 最初に配列を埋める
EGL は、get ステートメントに対して以下の疑似 DL/I コードを作成し、ホスト変数修飾子は、正しいレコード変数名を使用します。
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :STSCCST.customerNo)
STSCLOC (STQCLNO = :STSCLOC.locationNo)
STPCORD (STQCODN = :STPCORD.orderDateNo)
GN STPCORD };
EGL は、PCB 階層情報からデフォルトの SSA を作成するので、この方法で簡単に、EGL が使用する変数名をご使用のプログラムのレコード変数宣言と必ず 一致させることができます。 欠点として、この手法は、パーツおよび変数に別の名前を使用するという、一般的な慣例に従わない点があります。
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN = :myOrder.orderDateNo)
GN STPCORD };
myOrder.orderDateNo = "";
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN >= :myOrder.orderDateNo) // using >= instead of =
GN STPCORD };
この手法の欠点は、すべての明示的 I/O の場合と同様です。つまり、階層またはキー・フィールドが変更されても、 明示的 DL/I データベース I/O ステートメントは、自動的に変更されません。
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier = "myCustomer" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
myCustomer CustomerRecodPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20}; // オーダーの配列
get myOrderArray; // 最初に配列を埋める
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN = :myOrder.orderDateNo)
GN STPCORD };
この手法の長所は、暗黙的 DL/I データベース I/O を使用できることと、レコード変数および DL/I セグメント・レコードに別の名前を指定することができる点です。 欠点は、CustomerRecordPart、LocationRecordPart、および OrderRecordPart を使用するそれぞれの暗黙的 DL/I データベース I/O ステートメントごとに、修飾子として myCustomer を使用するようになる点です。