DL/I 예제

다음 DL/I 예제에서는 예제 DL/I 데이터베이스에 설명되어 있는 것과 동일한 예제 DL/I 데이터베이스를 사용합니다. 다음은 DL/I 데이터베이스 I/O의 일반적 기술에 대한 몇 가지 예제입니다.

상위 세그먼트 내에서 검색

기본 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)
  // 현재 항목 처리
  get next inParent myItem;
end
EGL이 get next inParent 문에 대해 다음 pseudo-DL/I 코드를 작성합니다.
GNP  STLCITM 

다른 키가 아닌 필드로 검색

호출에 대해 검색 인수(SSA)를 수정하여 DL/I 호출에서 검색 인수로서 세그먼트의 필드를 사용할 수 있습니다. 예를 들어, 고객 데이터베이스를 통해 읽고 신용 밸런스가 지정된 양보다 큰 각 고객의 고객 세그먼트와 신용 세그먼트를 검색하려면 다음과 같이 DL/I 호출 검색 인수를 정의하십시오.
  1. 신용 세그먼트(STSCSTA)에서 creditBalance 필드(STFCSBL)를 검색하려고 합니다. 이를 수행하려면 검색하려는 지정된 양을 포함하는 10진수 유형(12,2)의 변수를 정의하십시오(예: "targetBalance"). targetBalance에 대한 정의는 신용 세그먼트에서 creditBalance 필드에 대한 정의와 일치해야 합니다.
  2. myCrStatus 레코드에 대해 get next 문을 작성하십시오.
  3. 기본 코드를 수정하여 행에 #dli 지시문을 추가하십시오. creditBalance 필드의 양이 targetBalance보다 큰 세그먼트를 찾는 규정된 SSA를 추가하십시오.
  4. 신용 세그먼트에 해당하는 고객 세그먼트(STSCCST)를 검색하도록 경로 명령 코드(*D)를 포함시키십시오.
다음 샘플 코드가 이 프로세스를 설명합니다.
	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" }} 
  //변수 선언
  myCustomerPSB     CustomerPSBRecordPart; 
  myCustomer        CustomerRecordPart;
customerParm.customerNo의 값을 기반으로 고객 세그먼트를 검색하려고 합니다. 다음과 같이 이를 코드화하는 세 가지 방법이 있습니다.
  • 다음과 같이 customerParm.customerNo의 값을 myCustomer.customerNo에 지정한 후 암시적 DL/I I/O를 사용하십시오.
    myCustomer.customerNo = CustomerParm.customerNo;
    get myCustomer;
    이 경우 EGL은 정상적인 기본 SSA를 작성하고 그 결과 다음과 같은 의사 DL/I 코드가 만들어집니다.
    GU STSCCST (STQCCNO = :myCustomer.customerNo)
    이 기술의 장점은 매우 단순하다는 것입니다. 단점은 고객 번호를 세그먼트 레코드에 이동하는 데 성능 오버헤드가 아주 약간 발생한다는 점입니다.
  • 다음과 같이 #dli 지시문 및 명시적 DL/I I/O를 사용하면 customerParm.customerNo 필드를 호스트 변수로 사용할 수 있습니다.
    get myCustomer with #dli {
       GU  STSCCST (STQCCNO = :customerParm.customerNo) } ;
    이 기법은 고객 번호 이동에 따른 성능 오버헤드를 막아줍니다. 그러나 기본 #dli 지시문에 붙여넣기하는 시간이 다소 길어지므로 코드를 수정하여 매개변수 레코드에 정확한 레코드 변수 이름을 사용하십시오.
  • 다음과 같이 DLISegment 레코드에서 hostVarQualifier 특성을 추가하여 호스트 변수에 대한 규정자를 지정하십시오.
    Record CustomerRecordPart type DLISegment 
      {segmentName="STSCCST", keyItem="customerNo", 
       hostVarQualifier="customerParm" }
      10 customerNo char(6) { dliFieldName = "STQCCNO" }; // 키 필드
      ... 
    end
    그러면 다음과 같이 customerParm.customerNomyCustomer.customerNo에 먼저 지정하지 않고 암시적 DL/I I/O를 사용할 수 있습니다.
    get myCustomer;
    이 경우 EGL이 작성하는 의사 DL/I 코드는 다음과 같습니다.
    GU STSCCST (STQCCNO = :customerParm.customerNo)

    이 기법의 이점은 #dli 지시문을 직접 코드화하지 않아도 #dli 지시문에 대해 코드화해둔 동일한 의사 DL/I 코드가 얻어진다는 것입니다. 단점은 EGL이 이제 CustomerRecordPart를 사용하는 모든 암시적 DL/I 데이터베이스 I/O 문에 대한 규정자로 customerParm을 사용한다는 것입니다.

비루트 세그먼트 검색

암시적 DL/I 데이터베이스 I/O를 사용하여 비루트 세그먼트를 검색할 수 있습니다. EGL은 PCB에서 대상 세그먼트의 계층 구조 위치를 기반으로 전체 SSA 체인을 작성합니다. 그러나 계층 구조의 상위 레벨 세그먼트에 대해서는 EGL이 세그먼트에 대한 규정자로 사용할 프로그램 변수의 이름을 자동으로 판별할 수 없습니다.

고객 세그먼트 STSCCST가 위치 세그먼트 STSCLOC의 상위이고 위치 세그먼트의 데이터만 검색하려는 상황을 고려해 보십시오. 사용자의 프로그램에서 다음 레코드 변수를 정의했습니다.
myCustomer CustomerRecordPart; 
myLocation LocationRecordPart;
다음 get 문을 사용하는 경우:
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의 keyItemcustomerNo라는 것만 알고 있습니다.

이 문제점을 여러 방법으로 해결할 수 있습니다.
  • 기반으로 하는 레코드 파트와 동일한 이름으로 레코드 변수를 이름 지정할 수 있습니다. 예를 들어, myCustomer의 변수 선언을 CustomerRecordPart로 변경하십시오.
    CustomerRecordPart CustomerRecordPart;
    EGL이 동일한 의사 DL/I 코드를 작성합니다.
    GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo) 
      STSCLOC (STQCLNO = :myLocation.locationNo)

    EGL이 PCB 계층 구조 정보에서 기본 SSA를 작성하므로 이는 EGL이 사용하는 변수 이름을 사용자 프로그램의 레코드 변수 선언과 일치시키는 간단한 방법입니다. 단점은 이 기법은 파트와 변수에 다른 이름을 사용하는 일반 사례를 따르지 않는다는 점입니다.

  • 다음과 같이 #dli 지시문 및 명시적 DL/I 데이터베이스 I/O를 사용하십시오.
    get myLocation with #dli {
      GU STSCCST (STQCCNO = :myCustomer.customerNo)
        STSCLOC (STQCLNO = :myLocation.locationNo)

    이 기술의 장점은 사용되는 호스트 변수가 매우 분명하다는 점입니다. 호스트 변수 규정자 또는 필드 이름이 DL/I 세그먼트 레코드를 기반으로 하는 레코드 변수와 다른 경우 이는 사용하기 쉬운 기술입니다. 단점은 명시적 I/O의 경우와 동일합니다. 즉, 계층 구조나 키 필드가 변경되는 경우 명시적 DL/I 데이터베이스 I/O 문이 자동으로 변경되지 않습니다.

  • 다음과 같이 hostVarQualifier 특성을 포함하도록 CustomerRecordPart의 정의를 수정하십시오.
    Record CustomerRecordPart type DLISegment 
      { segmentName="STSCCST", keyItem="customerNo",
        hostVarQualifier = "myCustomer" } 
      10 customerNo char(6) { dliFieldName = "STQCCNO" }; // 키 필드
      ... 
    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를 사용한다는 것입니다.

2차 색인으로 검색

DL/I PSB는 종종 2차 색인으로 데이터베이스 구조에 액세스함을 표시하는 경우가 있습니다. 이러한 상황이 발생하면 데이터베이스 관리자는 런타임 PCB 정의에서 루트 세그먼트 옆에 색인 키 이름을 입력합니다. 사용자는 PSBRecord 내의 PCB 레코드에 secondaryIndex 특성을 포함시켜 2차 색인의 사용을 EGL에 알리십시오. 예를 들어, customerName이 2차 색인인 또 다른 고객 데이터베이스 보기가 있는 경우 다음과 같이 추가 PCB 레코드를 PSB 레코드 파트에 추가할 수 있습니다.
// 이름별 고객 데이터베이스 PCB
customerNamePCB DB_PCBRecord 
  { @PCB { pcbType = DB, pcbName = "STDCNAM", 
    secondaryIndex = "STUCCNM",
    hierarchy = [ @relationship { segmentRecord = "CustomerRecordPart" },
    ... ] }
  }

pcbName 특성은 런타임 PSB의 실제 DL/I 데이터베이스 PCB와 일치해야 합니다. secondaryIndex 특성은 데이터베이스 관리자가 런타임 PCB의 XDFLD문에 지정한 것과 동일한 필드 이름을 제공해야 합니다. 이제 PSB 레코드에는 계층 구조에 CustomerRecordPart를 포함하는 두 개의 PCB 레코드가 있습니다.

다음 예제와 같이 고객을 찾기 위해 get 문을 실행하는 경우:
myCustomer CustomerRecordPart;
get myCustomer;
EGL은 CustomerRecord 파트를 포함하는 PSB 레코드의 첫 번째 PCB 레코드를 기반으로 의사 DL/I 코드를 작성합니다.
2차 색인 데이터베이스가 PSB 레코드의 두 번째 PCB 레코드인 경우 다음 예제와 같이 usingPCB 키워드를 포함시켜 EGL이 올바른 PCB를 사용하도록 해야 합니다.
get myCustomer usingPCB customerNamePCB;
EGL이 다음 의사 DL/I 코드를 작성합니다.
GU STSCCST (STUCCNM = :myCustomer.customerName)
EGL은 get 문의 레코드 변수 이름(myCustomer)과 usingPCB 키워드로 지정된 PCB를 사용하여 다음 정보를 찾았습니다.
  • 세그먼트의 DL/I 이름(특성 segmentName = "STSCCST")
  • 2차 색인 필드의 DL/I 이름(특성 secondaryIndex = "STUCCNM")
  • 비교 값의 EGL 필드 이름(특성 dliFieldName = "STUCCNM" 및 해당 필드 이름 customerName)
일부 경우, 실제 데이터베이스에서 하위 레벨 세그먼트에 2차 색인이 있을 수 있습니다. 이 경우 데이터베이스 구조가 반전된 것입니다. 예를 들어, 주문 세그먼트의 orderReference 필드에 2차 색인이 있는 경우 프로그램 요구사항에 따라 해당 PCB 레코드에 반영되는 데이터베이스 계층 구조는 다음과 같습니다.
// 고객 데이터베이스의 오더 보기
ordersByReferencePCB DB_PCBRecord 
  { @PCB { pcbType = DB, pcbName = "STDCDBL", 
    secondaryIndex = "STFCORF",   // DL/I 이름 사용
    hierarchy = [ 
        @relationship { segmentRecord = "OrderRecordPart" }, 
        @relationship { segmentRecord = "LocationRecordPart", 
                                    parentRecord = "OrderRecordPart" }, 
        @relationship { segmentRecord = "CustomerRecordPart", 
                                    parentRecord = "LocationRecordPart" }, 
        @relationship { segmentRecord = "ItemRecordPart", 
                                    parentRecord = "OrderRecordPart" }
        ]}
  }; 
end 
주문 참조 번호가 각 고객과 주문마다 고유하다고 가정하면 위치 및 고객 세그먼트에 대해 키를 사용할 필요가 없습니다. ordersByReferencePCB가 기본 PCB라고 가정하면 다음과 같이 위치 및 고객 세그먼트에 대한 비교를 삭제하도록 SSA를 수정하여 주문과 고객 모두를 검색할 수 있습니다.
get myOrder, myCustomer with #dli{ 
  GU STPCORD*D (STQCODN = :myOrder.orderReference) 
    STSCLOC 
    STSCCST };

경로 호출을 사용하여 다중 세그먼트 액세스

종속자 세그먼트 레코드 오브젝트를 사용하여 EGL I/O 문을 호출하는 경우 루트에서 오브젝트까지의 경로에 있는 모든 세그먼트를 동시에 읽을 수 있습니다. 단순히 명령문에 경로 호출에 대한 레코드를 추가하여 이를 수행할 수 있습니다. 예를 들어, 고객 데이터베이스 예제에서 주문 세그먼트를 검색할 때 동일한 호출에서 고객, 위치, 주문 세그먼트를 읽을 수 있습니다.
get myCustomer, myLocation, myOrder;
이 명령문은 다음 DL/I 의사 코드를 생성합니다.
GU STSCCST*D (STQCCNO = :myCustomer.customerNo) 
   STSCLOC*D (STQCLNO = :myLocation.locationNo)
   STPCORD   (STQCDDN = :myOrder.orderDateNo)
get...forUpdate 문에서 D 명령 코드를 사용하는 경우 후속 replace 문은 검색된 모든 세그먼트에 영향을 미칩니다. 위치와 주문 세그먼트만을 대체하는 다음 예제에서처럼 replace 키워드에 대해 SSA에서 명시적 N 명령 코드를 지정하여 선택된 세그먼트의 교체를 방지할 수 있습니다.
get myCustomer, myLocation, myOrder forUpdate;
replace myOrder with #dli{
	REPL STSCCST*N
	     STSCLOC*N
       STPCORD };
D 명령 코드와 함께 get forUpdate 문을 따르는 delete 함수에 대한 기본 DL/I 호출 EGL 빌드는 검색된 각 세그먼트를 삭제하지 않습니다. 이는 delete 문에서 지정된 대상 세그먼트만 삭제합니다.

단일 I/O 문으로 모든 세그먼트 읽기

단일 I/O 문을 사용하여 데이터베이스의 모든 세그먼트를 읽을 수 있습니다. SSA 없이 DL/I get next 문을 실행하면 DL/I는 유형에 관계 없이 데이터베이스의 다음 세그먼트를 리턴합니다. 이 기술을 사용하려면 다음 단계를 따르십시오.
  1. 데이터베이스에서 최대 세그먼트를 나타내는 레코드에 대해 get next 문을 쓰십시오. 이는 사용자가 읽는 세그먼트가 할당된 메모리를 초과하지 않게 해줍니다.
  2. 기본 DL/I 호출을 코드에 추가하십시오. 단일 SSA를 삭제하도록 #dli 지시문을 편집하십시오.
  3. 데이터베이스에서 기타 세그먼트와 일치하는 레코드를 작성하십시오. 프로그램에서 레코드를 선언하고 각 레코드가 위의 1단계에서 사용된 레코드를 재정의하도록 지정하여 모든 레코드가 동일한 메모리 영역을 점유하게 하십시오.
  4. get next 문 뒤에 dliVar.segmentName을 선택하여 검색된 세그먼트 유형을 판별하십시오.
  5. 해당 레코드 구조에서 검색된 세그먼트에 액세스하십시오.
다음은 고객 데이터베이스의 모든 항목을 인쇄하는 코드 예제입니다. 이 예제에서 HistoryRecordPart는 최대 DLISegment 레코드입니다.
myHistory HistoryRecordPart
redefCustomer CustomerRecordPart {redefines=myHistory};
redefLocation LocationRecordPart {redefines=myHistory};
...


//유형에 상관 없이 히스토리 레코드로 다음 세그먼트 읽기
while (myHistory not EOF)
	get next myHistory with #dli{
		GN };

	//어떤 유형?
	case (dliVar.segmentName)
		when "STSCCST"                   // 고객임
			printCustomer();
		when "STSCLOC"                   // 위치임
			printLocation();
		...
	endend

동적 배열 사용

getget next 문을 사용하여 동적 배열에 대해 DL/I 세그먼트를 검색할 수 있습니다. 배열 자체에 대한 키 필드가 없으므로(배열 멤버에만 해당) EGL이 올바른 코드를 작성하도록 특별한 기술을 사용해야 합니다.

다음과 같이 레코드 변수와 동적 배열을 정의한 상황을 고려해 보십시오.
myCustomer CustomerRecordPart;
myLocation LocationRecordPart;
myOrder OrderRecordPart;
myOrderArray OrderRecordPart [] {maxsize = 20};  // 주문 배열
다음과 같이 get 문을 사용하여 먼저 배열을 채우고 get next 문을 사용하여 20개의 주문으로 된 두 번째 그룹을 검색할 수 있습니다.
myCustomer.customerNo = "123456";
myLocation.locationNo = "ABCDEF";
myOrderDateNo = "20050730A003";
get myOrderArray;                  // 먼저 배열 채우기
... do some processing
get next myOrderArray;          // 20개의 주문으로 된 다음 일괄처리 가져오기
EGL은 get 문에 대해 다음 의사 DL/I 코드를 작성합니다.
get myOrderArray with #dli{
  GU STSCCST (STQCCNO = :CustomerRecordPart.customerNo)
    STSCLOC (STQCLNO = :LocationRecordPart.locationNo)
    STPCORD (STQCODN = :OrderRecordPart.orderDateNo)
  GN STPCORD };
EGL은 get next 문에 대해 다음 의사 DLI 코드를 작성합니다.
get next myOrderArray with #dli{
  GN STPCORD };

get 문을 사용하여 20개 주문으로 된 첫 번째 일괄처리의 동적 배열을 채우려면 초기 GU 호출 이후 배열이 가득 차거나 DL/I에서 세그먼트 발생이 없어질 때까지 GN 호출이 계속 이어져야 합니다. EGL이 작성하는 의사 DL/I 코드에서 GU 호출은 첫 번째 주문 세그먼트를 검색합니다. EGL은 GN 호출을 루프로 처리하고 배열이 가득 차거나 DL/I에서 세그먼트 발생이 없어질 때까지 루프에 로직을 제공합니다. 마찬가지로 EGL은 get next 문을 루프로 처리하며 루프 제어 로직을 제공합니다.

get next 문은 두 번째 주문 일괄처리를 검색하기 위한 올바른 의사 DL/I 코드를 제공합니다. 그러나 get 문에 대한 의사 DL/I 코드가 매우 정확하지는 않아 호스트 변수의 규정자 이름이 사용자 프로그램의 레코드 변수 이름이 아닙니다. 이 문제점을 여러 방법으로 해결할 수 있습니다.
  • DL/I 데이터베이스의 세그먼트와 동일한 이름으로 DL/I 세그먼트 레코드의 이름을 지정하십시오. 또한 DL/I 데이터베이스의 세그먼트와 동일한 이름이 되도록 사용자의 레코드 변수 이름을 변경하십시오. 예를 들어, 다음에서 고객 레코드 파트 정의를 변경하십시오.
    Record CustomerRecordPart type DLISegment 
      { segmentName="STSCCST", keyItem="customerNo" } 
      10 customerNo char(6) { dliFieldName = "STQCCNO" }; // 키 필드
      ... 
    end
    다음으로 변경하십시오.
    Record STSCCST type DLISegment 
      { segmentName="STSCCST", keyItem="customerNo" } 
      10 customerNo char(6) { dliFieldName = "STQCCNO" }; // 키 필드
      ... 
    end
    위치 세그먼트(STSCLOC) 및 주문 세그먼트(STPCORD)에 대해서도 이와 같이 변경하십시오. 그런 다음, 다음과 같이 새 이름을 사용하도록 PSB 레코드를 변경하십시오.
    Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" } 
      // 데이터베이스 PCB
      customerPCB DB_PCBRecord { @PCB { pcbType = DB, pcbName = "STDCDBL", 
      hierarchy = [ @relationship { segmentRecord = "STSCCST" },
           @relationship {segmentRecord="STSCLOC",
                          parentRecord="STSCCST"},
           @relationship {segmentRecord="STPCORD",
                          parentRecord="STSCLOC"}
           ]}};
    
    end
    다음과 같이 레코드 변수와 myOrderArray의 선언을 변경하여 새 DL/I 세그먼트 레코드 파트를 참조하게 하십시오.
    STSCCST STSCCST;
    STSCLOC STSCLOC;
    STPCORD STPCORD;
    myOrderArray STPCORD [] {maxsize = 20};  // 주문 배열
    이제 다음 get 문을 실행하는 경우:
    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이 사용하는 변수 이름을 사용자 프로그램의 레코드 변수 선언과 일치시키는 간단한 방법입니다. 단점은 파트와 변수에 다른 이름을 사용하는 일반 사례를 따르지 않는다는 점입니다.

  • 다음과 같이 #dli 지시문 및 명시적 DL/I 데이터베이스 I/O를 사용하십시오.
    get myOrderArray with #dli{
      GU STSCCST (STQCCNO = :myCustomer.customerNo)
        STSCLOC (STQCLNO = :myLocation.locationNo)
        STPCORD (STQCODN = :myOrder.orderDateNo)
      GN STPCORD };
    이 기술의 장점은 사용되는 호스트 변수가 매우 분명하다는 점입니다. 이 기술은 기본 DL/I 코드를 변경해야 하는 경우(예를 들어, 고객의 첫 번째 주문 번호를 모르는데 다음 DL/I 코드를 사용하려고 하는 경우) 특히 유용합니다.
    myOrder.orderDateNo = "";
    get myOrderArray with #dli{
      GU STSCCST (STQCCNO = :myCustomer.customerNo)
        STSCLOC (STQCLNO = :myLocation.locationNo)
        STPCORD (STQCODN >= :myOrder.orderDateNo)   // 대신 >= 사용
      GN STPCORD };

    이 기술의 단점은 명시적 I/O의 경우와 동일합니다. 즉, 계층 구조나 키 필드가 변경되어도 명시적 DL/I 데이터베이스 I/O 문이 자동으로 변경되지 않습니다.

  • 각 DL/I 세그먼트 레코드의 정의를 수정하여 사용자 프로그램 레코드 변수의 이름과 함께 hostVarQualifier 특성을 포함시키십시오. 예를 들어, CustomerRecordPart를 다음으로 변경하십시오.
    Record CustomerRecordPart type DLISegment 
      { segmentName="STSCCST", keyItem="customerNo",
        hostVarQualifier = "myCustomer" } 
      10 customerNo char(6) { dliFieldName = "STQCCNO" }; // 키 필드
      ... 
    end
    다음 레코드 선언 및 get 문을 사용하는 경우:
    myCustomer CustomerRecodPart;
    myLocation LocationRecordPart;
    myOrder OrderRecordPart;
    myOrderArray OrderRecordPart [] {maxsize = 20};  // 오더 배열
    get myOrderArray;                  // 먼저 배열 채우기
    EGL이 올바른 의사 DL/I 코드를 생성합니다.
    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 세그먼트 레코드에 대해 서로 다른 이름을 가질 수 있다는 점입니다. 단점은 EGL이 이제 CustomerRecordPart, LocationRecordPart, OrderRecordPart를 사용하는 모든 암시적 DL/I 데이터베이스 I/O 문에 대한 규정자로 myCustomer를 사용한다는 것입니다.