Die Standardanweisung GET NEXT beginnt an der derzeitigen Position in der Datenbank und durchsucht die gesamte Datenbank nach dem nächsten Vorkommen des Zielsegments unter übergeordneten Segmenten. Verwenden Sie die Anweisung GET NEXT INPARENT, um den Suchbereich auf die derzeit eingerichtete abhängige Kette einzuschränken.
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)
Der Vorteil dieses Verfahrens ist, dass es sehr einfach ist. Der Nachteil liegt in sehr geringen Leistungseinbußen beim Verschieben der Kundennummer in den Segmentdatensatz.get myCustomer with #dli {
GU STSCCST (STQCCNO = :customerParm.customerNo) } ;
Mit diesem Verfahren werden die Leistungseinbußen beim Verschieben der Kundennummer vermieden.
Es dauert jedoch ein wenig länger, Daten in die Standard-#dli-Direktive einzufügen und den Code dann zu ändern, um den korrekten Variablennamen des Datensatzes für den Parameterdatensatz zu verwenden.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)
Der Vorteil dieses Verfahrens besteht darin, dass es zum selben Pseudo-DL/I-Code führt, den Sie für die #dli-Direktive geschrieben haben, jedoch ohne dass Sie den Code für die #dli-Direktive tatsächlich schreiben müssen. Der Nachteil ist, dass in EGL nun customerParm als Qualifikationsmerkmal für alle impliziten E/A-Anweisungen für die DL/I-Datenbank verwendet wird, für die 'CustomerRecordPart' verwendet wird.
Sie können die implizite DL/I-Datenbank-Ein-/Ausgabe zum Abrufen von Nicht-Stammsegmenten verwenden. In EGL wird die gesamte Kette von SSAs anhand der hierarchischen Position des Zielsegments im PCB erstellt. Für Segmente höherer Ebene in der Hierarchie kann in EGL jedoch nicht automatisch der Name der Programmvariable für die Verwendung als Qualifikationsmerkmal für das Segment bestimmt werden.
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
get myLocation;
In EGL wird dann der folgende Pseudo-DL/I-Code erstellt: GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
Beachten Sie, dass die Variable myCustomer, die auf 'CustomerRecordPart' basiert, in EGL nicht gefunden werden konnte, während die Variable myLocation dem Segment STSCLOC ordnungsgemäß zugeordnet werden konnte. In EGL ist nur bekannt, dass myLocation vom Typ 'LocationRecordPart' ist, dessen übergeordnetes Segment 'CustomerRecordPart' ist, und dass 'keyItem' für 'CustomerRecordPart' customerNo ist.
CustomerRecordPart CustomerRecordPart;
In EGL wird dann derselbe Pseudo-DL/I-Code erstellt: GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
Da die Standard-SSAs in EGL aus den PCB-Hierarchieinformationen erstellt werden, ist dies eine einfache Möglichkeit, um sicherzustellen, dass die in EGL verwendeten Variablennamen mit den Datensatzvariablendeklarationen Ihres Programms übereinstimmen. Der Nachteil ist, dass dieses Verfahren nicht der allgemeinen Praxis, unterschiedliche Namen für Abschnitte und Variablen zu verwenden, entspricht.
get myLocation with #dli {
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
Der Vorteil dieses Verfahrens ist, dass sehr deutlich ist, welche Hostvariablen verwendet werden. Dieses Verfahren ist einfach anzuwenden, wenn das Qualifikationsmerkmal oder der Feldname der Hostvariable sich von der Datensatzvariable unterschiedet, die auf dem DL/I-Segmentdatensatz basiert. Der Nachteil ist derselbe wie für alle expliziten Ein-/Ausgaben: Wenn die Hierarchie oder die Schlüsselfelder geändert werden, wird die explizite E/A-Anweisung der DL/I-Datenbank nicht automatisch geändert.
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo",
hostVarQualifier = "myCustomer" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
Verwenden Sie nun die folgende GET-Anweisung:get myLocation;
In EGL wird dann der korrekte Pseudo-DL/I-Code erstellt:GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
Der Vorteil dieses Verfahrens ist, dass Sie die implizite Ein-/Ausgabe der DL/I-Datenbank und unterschiedliche Namen für die Datensatzvariablen und die DL/I-Segmentdatensätze verwenden können. Der Nachteil ist, dass in EGL nun myCustomer als Qualifikationsmerkmal für alle impliziten E/A-Anweisungen für die DL/I-Datenbank verwendet wird, für die 'CustomerRecordPart' verwendet wird.
// database PCB for customer by Name
customerNamePCB DB_PCBRecord
{ @PCB { pcbType = DB, pcbName = "STDCNAM",
secondaryIndex = "STUCCNM",
hierarchy = [ @relationship { segmentRecord = "CustomerRecordPart" },
... ] }
}
Die Eigenschaft 'pcbName' muss mit einem tatsächlichen DL/I-Datenbank-PCB im Laufzeit-PSB übereinstimmen. Mit der Eigenschaft 'secondaryIndex' muss derselbe Feldname bereitgestellt werden, den der Datenbankadministrator in der XDFLD-Anweisung des Laufzeit-PCBs angegeben hat. Es gibt nun zwei PCB-Datensätze im PSB-Datensatz, in deren Hierarchie 'CustomerRecordPart' vorhanden ist.
myCustomer CustomerRecordPart;
get myCustomer;
In EGL wird dann basierend auf dem ersten PCB-Datensatz im PSB-Datensatz der Pseudo-DL/I-Code erstellt, der den Abschnitt 'CustomerRecord' enthält.get myCustomer usingPCB customerNamePCB;
In EGL dann wird der folgende Pseudo-DL/I-Code erstellt: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;
Mit dieser Anweisung wird der folgende DL/I-Pseudocode generiert.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 };
Mit dem Standard-DL/I-Aufruf, der in EGL für eine DELETE-Funktion durchgeführt wird, die auf eine GET FORUPDATE-Anweisung mit Befehlscodes D folgt, werden nicht alle abgerufenen Segmente gelöscht. Es wird nur das in der DELETE-Anweisung angegebene Zielsegment gelöscht.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
Sie können die Anweisungen GET und GET NEXT zum Abrufen von DL/I-Segmenten in eine dynamische Feldgruppe verwenden. Da für die Feldgruppe selbst kein Schlüsselfeld vorhanden ist (nur für Elemente der Feldgruppe), müssen Sie einige besondere Verfahren anwenden, damit in EGL der korrekte Code verwendet wird.
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20}; // array of orders
myCustomer.customerNo = "123456";
myLocation.locationNo = "ABCDEF";
myOrderDateNo = "20050730A003";
get myOrderArray; // fill the array the first time
... do some processing
get next myOrderArray; // get the next batch of 20 orders
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 };
Zum Füllen der dynamischen Feldgruppe für den ersten Batch von 20 Bestellungen mit einer GET-Anweisung ist ein erstmaliger GU-Aufruf gefolgt von einer Schleife von GN-Aufrufen erforderlich, bis die Feldgruppe voll ist oder für DL/I keine Segmentvorkommen mehr vorhanden sind. Im Pseudo-DL/I-Code, der in EGL erstellt wird, wird durch den GU-Aufruf das erste Segment für die Bestellung abgerufen. In EGL wird der GN-Aufruf als Schleife behandelt und die Logik für die Schleife bereitgestellt, die durchgeführt wird, bis die Feldgruppe voll ist oder für DL/I keine Segmentvorkommen mehr vorhanden sind. Auf ähnliche Weise wird die GET NEXT-Anweisung in EGL als Schleife behandelt und die Schleifensteuerungslogik für Sie bereitgestellt.
Record CustomerRecordPart type DLISegment
{ segmentName="STSCCST", keyItem="customerNo" }
10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key field
...
end
in den folgenden: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; // fill the array the first time
In EGL wird dann für die GET-Anweisung der folgende Pseudo-DL/I-Code erstellt und für die Qualifikationsmerkmale für die Hostvariablen werden die korrekten Namen für die Datensatzvariablen verwendet:get myOrderArray with #dli{
GU STSCCST (STQCCNO = :STSCCST.customerNo)
STSCLOC (STQCLNO = :STSCLOC.locationNo)
STPCORD (STQCODN = :STPCORD.orderDateNo)
GN STPCORD };
Da die Standard-SSAs in EGL aus den PCB-Hierarchieinformationen erstellt werden, ist dies eine einfache Möglichkeit, um sicherzustellen, dass die in EGL verwendeten Variablennamen mit den Datensatzvariablendeklarationen Ihres Programms übereinstimmen. Der Nachteil ist, dass dieses Verfahren nicht der allgemeinen Praxis, unterschiedliche Namen für Abschnitte und Variablen zu verwenden, entspricht.
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 };
Der Nachteil dieses Verfahrens ist derselbe wie für alle expliziten Ein-/Ausgaben: Wenn die Hierarchie oder die Schlüsselfelder geändert werden, wird die explizite E/A-Anweisung der DL/I-Datenbank nicht automatisch geändert.
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}; // array of orders
get myOrderArray; // fill the array the first time
get myOrderArray with #dli{
GU STSCCST (STQCCNO = :myCustomer.customerNo)
STSCLOC (STQCLNO = :myLocation.locationNo)
STPCORD (STQCODN = :myOrder.orderDateNo)
GN STPCORD };
Der Vorteil dieses Verfahrens ist, dass Sie die implizite Ein-/Ausgabe der DL/I-Datenbank und unterschiedliche Namen für die Datensatzvariablen und die DL/I-Segmentdatensätze verwenden können. Der Nachteil ist, dass in EGL nun 'myCustomer' als Qualifikationsmerkmal für alle impliziten E/A-Anweisungen für die DL/I-Datenbank verwendet wird, für die 'CustomerRecordPart', 'LocationRecordPart' und 'OrderRecordPart' verwendet werden.