Example DL/I database

To provide a consistent experience and to let each example build on others, this documentation uses the same example DL/I database wherever possible. This customer database has basic customer information at the root level. For each customer there are segments for credit status, history, and individual locations. Each location has order segments, and each order has item segments.

Database layout

The following database is named CUSTOMER:
Customer database diagram
The following details refer to the example database:
  • The location number in the location segment is unique for each customer.
  • The order segment is a concatenated segment containing data from two segments that are connected by a logical relationship. The item description, quantity on hand, quantity on order, quantity reserved, unit price, and unit of issue are all physically stored in a separate inventory database. From the program's point of view, due to the logical relationship between the two segments, this information is presented as if it was part of the order item segment.
  • There is only one credit segment per customer so no key field is necessary.
  • The history segment is a variable length segment.

EGL DLISegment Records

EGL represents each of these segments in your program as records of type DLISegment. The following code sample shows how you can define this database structure in EGL. From time to time we will also show examples of DL/I calls using DL/I versions of segment and field names (8 characters maximum). Those DL/I names are also shown in the example.
//define records to match segments in DL/I db
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

Record LocationRecordPart type DLISegment 
{ segmentName="STSCLOC", keyItem="locationNo" }
	10 locationNo char(6)      { dliFieldName = "STQCLNO" };  //key field
	10 locationName char(25)   { dliFieldName = "STFCLNM" };
	10 locationAddr1 char(25)  { dliFieldName = "STFCLA1" };
	10 locationAddr2 char(25)  { dliFieldName = "STFCLA2" };
	10 locationAddr3 char(25)  { dliFieldName = "STFCLA3" };
end

Record OrderRecordPart type DLISegment 
{ segmentName="STPCORD", keyItem="orderDateNo" }
	10 orderDateNo char(12)       { dliFieldName = "STQCODN" };  //key field
	10 orderReference char(25)    { dliFieldName = "STFCORF" };
	10 orderItemCount num(6)      { dliFieldName = "STFCOIC" };
	10 orderAmount decimal(12,2)  { dliFieldName = "STFCOAM" };
end

Record ItemRecordPart type DLISegment 
{ segmentName="STLCITM", keyItem="itemKey" }
	10 itemKey char(8);            { dliFieldName = "STKCCKEY" }; //key field
		15 itemInventoryNo char(6)   { dliFieldName = "STKCIIN" };
		15 itemLineNo smallint       { dliFieldName = "STQCILI" };
	10 itemQtyOrdered num(6)       { dliFieldName = "STFCIQO" };
	10 itemQtyShipped num(6)       { dliFieldName = "STFCIQS" };
	10 itemQtyBackOrdered num(6)   { dliFieldName = "STFCIQB" };
	10 itemAmount decimal(12,2)    { dliFieldName = "STFCIAM" };
	10 itemNumber char(6)          { dliFieldName = "STQIINO" };
	10 itemDescription char(25)    { dliFieldName = "STFIIDS" };
	10 itemQtyOnHand num(6)        { dliFieldName = "STFIIQH" };
	10 itemQtyOnOrder num(6)       { dliFieldName = "STFIIOH" };
	10 itemQtyReserved num(6)      { dliFieldName = "STFIIQR" };
	10 itemUnitPrice char(6)       { dliFieldName = "STFIIPR" };
	10 itemUnitOfIssue char(1)     { dliFieldName = "STFIIUN" };
end

Record CreditRecordPart type DLISegment 
{ segmentName="STSCSTA" }
	10 creditLimit decimal(12,2)   { dliFieldName = "STFCSCL" };
	10 creditBalance decimal(12,2) { dliFieldName = "STFCSBL" };
end

Record HistoryRecordPart type DLISegment 
{ segmentName="STSCHIS", lengthItem="historySegmentLength", 
  keyItem="historyDateNo" }
	10 historySegmentLength smallint { dliFieldName = "STGCSL" };
	10 historyDateNo char(12)        { dliFieldName = "STQCHDN" };
	10 historyReference char(25)     { dliFieldName = "STFCHRF" };
	10 historyItemCount smallint     { dliFieldName = "STFCHIC" };
	10 historyAmount decimal(12,2)   { dliFieldName = "STQCHAM" };
	10 historyStatus char(77)        { dliFieldName = "STQCLOS" };
end

IMS PSB

In the following PSB definition on the host, the DBDNAME is set to CUSTOMER, the name of the database. A PCB is defined with the name STDCDBL; the customerPCB in the next section sets the pcbName property to this name.
         TITLE 'PSB FOR PROCESSING SAMPLE DATA BASES'
ELAALT   PCB    TYPE=TP,MODIFY=YES
ELAEXP   PCB    TYPE=TP,MODIFY=YES,EXPRESS=YES
STDCDBL  PCB    TYPE=DB,DBDNAME=CUSTOMER,PROCOPT=AP,KEYLEN=50,POS=S
         SENSEG NAME=STSCCST,PARENT=0
         SENSEG NAME=STSCLOC,PARENT=STSCCST
         SENSEG NAME=STPCORD,PARENT=STSCLOC
         SENSEG NAME=STLCITM,PARENT=STPCORD
         SENSEG NAME=STSCSTA,PARENT=STSCCST
         SENSEG NAME=STSCHIS,PARENT=STSCCST
         PSBGEN LANG=ASSEM,CMPAT=YES,PSBNAME=STBICLG
         END 

EGL PSBRecord

The following code represents the IMS™ PSB in the EGL program:
//define overall db layout in PSB
Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" }
	// three PCBs required for CBLTDLI on IMS
	iopcb IO_PCBRecord { @PCB { pcbType = PCBKind.TP } };
	elaalt ALT_PCBRecord { @PCB { pcbType = PCBKind.TP } };
	elaexp ALT_PCBRecord { @PCB { pcbType = PCBKind.TP } };
	
	// database PCB
	customerPCB DB_PCBRecord { @PCB {
		pcbType = DB,
		pcbName = "STDCDBL",
		hierarchy = [
			@relationship { segmentRecord = "CustomerRecordPart" },
			@relationship { 
				segmentRecord = "LocationRecordPart", parentRecord = "CustomerRecordPart" },
			@relationship { 
				segmentRecord = "OrderRecordPart", parentRecord = "LocationRecordPart" },
			@relationship { 
				segmentRecord = "ItemRecordPart", parentRecord = "OrderRecordPart" },
			@relationship { 
				segmentRecord = "CreditRecordPart", parentRecord = "CustomerRecordPart" },
			@relationship { 
				segmentRecord = "HistoryRecordPart", parentRecord = "CustomerRecordPart" }]}};
end

Sample EGL program

The following program outline is set up to use the CUSTOMER database:
program PrintCatalog type basicProgram { alias="PRINT",
	@DLI{ 		
		psb = "myPSB", 		
		callInterface = CBLTDLI	} }

	//create variables for the records
	myCustomer  CustomerRecordPart;
	myLocation  LocationRecordPart;
	myOrder     OrderRecordPart;
	myItem      ItemRecordPart;
	myCrStatus  CreditRecordPart
	myHistory   HistoryRecordPart

	myPSB       CustomerPSBRecordPart; 

	function main()
	...
	end
end

Feedback