DL/I 함수 호출
본 장에서는 DL/I 함수의 사용법에 대해 설명한다.
1. DL/I 함수
DL/I(Data Language/I)는 COBOL 또는 PL/I 언어로 작성된 애플리케이션에서 HiDB 데이터베이스에 접근하기 위해 호출하는 인터페이스 모듈이다. 일반 애플리케이션이 HiDB의 데이터를 조회하거나 갱신하기 위해서는 반드시 DL/I가 제공하는 기능과 형식을 따라 호출해야 한다.
다음은 COBOL에서 사용하는 DL/I 호출 문장형식이다.
CALL 'CBLTDLI' USING DLI-function PCB-mask Segment-io-area Segment-search-arguments
CBLTDLI는 COBOL에서 DL/I를 호출할 때 사용하는 인터페이스 모듈 이름이다.
다음은 COBOL에서 AIB를 사용하여 호출하는 DL/I 호출 문장형식이다.
CALL 'AERTDLI' USING DLI-function AIB-mask Segment-io-area Segment-search-arguments
AERTDLI는 COBOL에서 AIB를 이용하여 DL/I를 호출할 때 사용하는 인터페이스 모듈 이름이다.
다음은 PL/I 에서 사용하는 DL/I 호출 문장형식이다.
CALL 'PLITDLI' ( Parameter count DLI-function PCB-mask Segment-io-area Segment-search-arguments )
PLITDLI는 PL/I에서 DL/I를 호출할 때 사용하는 인터페이스 모듈 이름이다.
호출과 함께 넘기는 파라미터들은 DL/I 호출 전에 사용할 함수에 적합한 값들로 설정한다. DL/I 호출은 호출문장과 호출에 필요한 각종 정보를 담고 있는 파라미터들로 구성된다.
다음은 DL/I 호출에 사용되는 파라미터에 대한 설명이다. 단, Paramter count는 PLITDLI 모듈을 사용할 경우에만 기술한다.
파라미터 | 설명 |
---|---|
Parameter count |
PLITDLI 모듈에서만 사용하는 파라미터로써 해당 파라미터를 제외한 나머지 파라미터의 수를 기술한다. |
DLI-function |
세그먼트 조회, 삽입, 삭제, 갱신 등 DL/I에서 제공하는 여러 가지 기능 중 애플리케이션에서 사용하기 원하는 기능을 정의하는 파라미터이다. |
PCB-mask |
애플리케이션에서 DL/I 호출 후 반환되는 상태코드, 세그먼트 이름 등을 담기 위해 정의된 데이터 구조체 파라미터이다. |
Segment-io-area |
세그먼트 조회 후 반환된 데이터가 담기거나 세그먼트의 삽입 또는 갱신을 위한 데이터를 DL/I에 전달하기 위해 사용하는 파라미터 영역이다. |
Segment-search-arguments |
조회 또는 처리하기 원하는 특정 세그먼트의 검색 조건을 기술하는 파라미터로 한 개 이상의 세그먼트 이름과 조건 문장으로 구성된다. |
AIB-mask |
애플리케이션에서 AERTDLI 인터페이스를 사용하여 DL/I 호출 후 반환되는 리턴코드, PCB-mask 주소 등을 담기 위해 정의된 데이터 구조체 파라미터이다. |
2. DL/I 기능
DL/I 호출문장의 첫 번째 파라미터로 DL/I에서 제공하는 여러 가지 기능 중 사용하기 원하는 기능을 설정한다. DL/I에서 제공하는 기능은 크게 3가지로 구분할 수 있다.
-
Get
데이터베이스로부터 세그먼트의 데이터를 조회하기 위해서 사용하는 기능이다.
기능 설명 GU(Get Unique)
*GHU(Get Hold Unique)
특정 세그먼트를 직접 조회한다. 순차적 처리의 첫 번째 세그먼트 인스턴스 위치를 선정할 때 사용한다. 조회대상 조건은 SSA 파라미터에 기술한다.
GN(Get Next)
*GHN(Get Hold Next)
세그먼트를 순차적으로 조회한다. 현재 위치에서 계층경로를 따라 다음 세그먼트 인스턴스로 이동하여 조회한다.
GNP(Get Next in Parent)
*GHNP(Get Hold Next in Parent)
GN과 같은 기능을 하며, 부모 세그먼트에 종속된 세그먼트만을 순차적으로 조회한다. 설정된 부모 세그먼트의 종속된 세그먼트 내에서만 조회가 이루어진다. 부모 세그먼트는 GU 기능에 의해 조회된 세그먼트로 사전에 설정된다.
-
Update
데이터베이스에 데이터를 삽입하거나 수정 또는 삭제하기 위해서 사용하는 기능이다.
기능 설명 ISRT(Insert)
세그먼트에 새로운 데이터를 추가할 때 사용한다.
DLET(Delete)
세그먼트의 데이터를 삭제할 때 사용한다.
REPL(Replace)
세그먼트의 데이터를 변경할 때 사용한다.
-
기타
시스템 서비스 관련 기능이다.
기능 설명 CHKP, SYMCHKP(Checkpoint)
RDB의 Commit과 같은 개념으로 현재까지 프로그램이 수정한 내용을 모두 DB에 반영하며, SYMCHKP(Symbolic checkpoint)로 전달한 주소공간에 있는 데이터를 백업한다.
XRST(Extended Restart)
SYMCHKP로 백업한 데이터를 전달한 주소공간에 되돌린다.
SYNC(Synchronization Checkpoint)
CHKP와 동일한 기능을 수행한다.
ROLL, ROLB(Rollback)
프로그램이 마지막 commit 이후로 DB에 요청한 동작을 모두 되돌린다. ROLL의 경우 종료 코드 U00778로 프로그램을 종료한다.
APSB(Allocate PSB)
사용할 리소스(PSB)를 로드하여 메모리를 할당한다. AERTDLI 인터페이스를 사용하여 DL/I 함수를 호출하기 전에 호출해야 한다.
DPSB(Deallocate PSB)
APSB를 사용하여 할당한 리소스를 해제한다. AERTDLI 인터페이스 사용을 종료할 때 호출한다.
*H(Hold) 문자가 붙은 Get 기능은 세그먼트를 수정(REPL) 또는 삭제(DLET)하기 전 사용되는 기능이다. REPL과 DLET 기능을 호출하기 전에 반드시 H 문자가 붙은 Get 기능을 사용하여 세그먼트를 조회하는 이유는 다른 사용자로 인해 해당 데이터가 수정 또는 삭제되지 않도록 Lock을 설정하기 위해서이다. |
3. PCB Mask
IMS 시스템에서는 애플리케이션의 DL/I 함수 호출에 대한 여러 가지 결과 정보를 PCB에 설정한다. 애플리케이션은 PCB 구조를 담고 있는 PCB Mask와 PCB Mask의 각 필드를 참조함으로써 DL/I 호출에 대한 성공 또는 실패 여부를 확인할 수 있다.
DL/I 호출의 두 번째 파라미터인 PCB Mask는 Database name, Segment level number, Status Code 등 총 9개의 항목으로 구성되며, 그 중 5개의 항목을 개발자가 참조하게 된다. 특히 Status Code는 DL/I 호출에 대한 처리결과 코드가 저장되는 항목으로 애플리케이션에서 처리결과에 따른 작업을 분기할 때 비교 대상으로 빈번하게 사용되는 항목이다.
나머지 segment level number 또는 segment name 항목은 DL/I가 최종적으로 작업한 세그먼트의 정보가 담기게 되므로 unqualified GN 또는 GNP 호출에서 마지막으로 조회한 세그먼트를 알 수 있으며, 에러가 발생한 경우에도 이를 참조하여 에러 대상 세그먼트를 파악할 수 있다.
다음은 COBOL 프로그램에서 구현한 PCB Mask의 한 예이다.
01 SEGMENT1-PCB-MASK. 05 SPCB-DBD-NAME PIC X(8). 05 SPCB-SEGMENT-LEVEL PIC X(2). 05 SPCB-STATUS-CODE PIC X(2). 05 SPCB-PROC-OPTIOINS PIC X(4). 05 FILLER PIC S9(5) COMP. 05 SPCB-SEGMENT-NAME PIC X(8). 05 SPCB-KEY-LENGTH PIC S9(5) COMP. 05 SPCB-NUMB-SENS-SEGS PIC S9(5) COMP. 05 SPCB-KEY PIC X(11).
다음은 PCB Mask의 필드 구성에 대한 내용을 정리한 표이다.
필드명 | 길이(Byte) | 설명 |
---|---|---|
Database name |
8 |
접근한 세그먼트가 속해 있는 데이터베이스 이름이 담긴다. |
Segment level number |
2 |
데이터베이스 내의 현재 세그먼트 레벨 번호이다. 접근한 세그먼트가 루트 세그먼트일 경우 "01"이 담긴다. |
Status Code |
2 |
DL/I를 호출한 후 함수 처리결과에 대한 상태코드가 설정된다. 자세한 내용은 DL/I 상태 코드를 참고한다. |
Processing options |
4 |
프로그램이 발생시킬 수 있는 호출 타입에 대한 코드가 설정된다. 프로그램이 어떤 처리가 가능한지 알려주는 코드로 PSBGEN를 수행하는 경우 PROCOPT 파라미터로 지정한 값이 전달된다. |
Reserved for IMS |
4 |
IMS가 내부적으로 사용하는 필드로 애플리케이션에서는 사용하지 않는다. |
Segment name |
8 |
정상적으로 호출이 종료된 경우 접근했던 세그먼트 중 가장 마지막 세그먼트 이름이 설정된다. 호출이 실패한 경우는 요청한 세그먼트의 가장 마지막 세그먼트 이름이 담긴다. |
Length of key |
4 |
Key feedback area의 현재 길이가 담긴다. |
Number of sensitive segments |
4 |
바이너리 필드로 애플리케이션이 감지할 수 있는 세그먼트 타입의 번호가 담긴다. |
Key feedback area |
var length |
조회 또는 삽입될 때 접근한 세그먼트의 연쇄키(Concatenated key)가 담긴다. 연쇄키는 접근한 모든 레벨의 세그먼트 키 필드 값을 순차적으로 조합한 키를 의미한다. |
Status Code
Status Code는 DL/I 호출의 처리 결과에 대한 정보를 알려주는 코드로서 애플리케이션에서 이를 참조하여 적절한 처리를 진행한다. DL/I 호출이 정상적으로 처리를 완료하면 공백의 값을 반환한다.
다음은 주요 Status Code에 대한 설명이다.
코드 | 설명 |
---|---|
GA |
최하위 레벨의 세그먼트 레코드를 다 읽고 다음 상위 세그먼트를 읽기 전에 반환되는 코드로 Qualified 호출에서는 발생하지 않는다. 최하위 계층 세그먼트의 인스턴스가 더 이상 존재하지 않는 경우 발생하며 처리에는 영향이 없는 정보성 코드이다. |
GB |
순차적 조회될 때 계층경로를 따라 모든 데이터를 조회하고 데이터베이스 끝에 다다른 경우 반환되는 코드이다. 데이터베이스의 끝을 알리는 코드로 GN에서는 발생하나 GNP에서는 발생하지 않는다. |
GE |
제시한 조건에 일치하는 세그먼트 인스턴스를 찾지 못한다. |
GK |
Unqualified GN 또는 GNP를 호출하는 경우 동일한 계층 레벨에서 다른 세그먼트 타입이 발견되었을 때 반환되는 코드이다. 동일 레벨에서 다른 타입의 세그먼트가 조회된 경우에 발생하며 처리에는 영향을 주지 않는 정보성 코드이다. |
GA와 GK는 처리가 성공적으로 완료된 경우에 반환되는 정보성 Status Code이다. Status Code 중 GA와 GB는 자주 반환되는 코드이므로 개념을 잘 이해할 필요가 있다. |
다음은 각 함수별로 반환되는 주요 Status Code를 정리한 표이다. Status Code에 대한 더 자세한 사항은 DL/I 상태 코드를 참고한다.
GU/GHU | GN/GHN | GNP/GHNP | REPL/DLET | ISRT | |
---|---|---|---|---|---|
GA |
− |
○ |
○ |
− |
− |
GB |
− |
○ |
− |
− |
− |
GE |
○ |
○ |
○ |
− |
− |
GK |
− |
○ |
○ |
− |
− |
4. AIB Mask
AERTDLI 인터페이스에서는 AIB Mask를 사용하여 DL/I 함수를 호출한다.
애플리케이션은 IMS 시스템을 이용하기 위해 사용할 리소스 이름을 AIB Mask에 설정하여 사용한다. AERTDLI에서는 AIB-mask에 PCB-mask 주소를 전달하여 애플리케이션에서 참조하게 된다.
다음은 COBOL 프로그램에서 구현한 AIB Mask의 한 예이다.
01 AIB. 05 AIBRID PIC x(8). 05 AIBRLEN PIC 9(9) USAGE BINARY. 05 AIBRSFUNC PIC x(8). 05 AIBRSNM1 PIC x(8). 05 AIBRSNM2 PIC x(8). 05 AIBRESV1 PIC x(8). 05 AIBOALEN PIC 9(9) USAGE BINARY. 05 AIBOAUSE PIC 9(9) USAGE BINARY. 05 AIBRESV2 PIC x(12). 05 AIBRETRN PIC 9(9) USAGE BINARY. 05 AIBREASN PIC 9(9) USAGE BINARY. 05 AIBERRXT PIC 9(9) USAGE BINARY. 05 AIBRESA1 USAGE POINTER. 05 AIBRESA2 USAGE POINTER. 05 AIBRESA3 USAGE POINTER. 05 AIBRESV4 PIC x(40). 05 AIBRSAVE OCCURS 18 TIMES USAGE POINTER. 05 AIBRTOKN OCCURS 6 TIMES USAGE POINTER. 05 AIBRTOKC PIC x(16). 05 AIBRTOKV PIC x(16). 05 AIBRTOKA OCCURS 2 TIMES PIC 9(9) USAGE BINARY.
다음은 AIB Mask의 필드 구성에 대한 내용을 정리한 표이다(HiDB AERTDLI에서 사용되는 필드에 대해서만 기술한다).
필드명 | 길이(Byte) | 설명 |
---|---|---|
Resource name |
8 |
APSB, DPSB를 호출하는 경우 PSB 이름을 지정해야 한다. 다른 DL/I를 호출하는 경우 PCB 이름을 지정해야 한다. (예: AIBRSNM1, AIBRSNM2) |
Resource address |
DL/I 함수를 호출한 후 PCB Mask의 주소가 반환된다. (예: AIBRESA1, AIBRESA2..) |
|
Return code |
4 |
AIBTDLI의 리턴코드가 반환된다. 0은 성공, 그 이외는 에러코드가 반환된다. (예: AIBRETRN) |
5. SSA
SSA(Segment Search Argument)는 DL/I 호출에 대한 처리과정에서 필요한 조건 정보를 담고 있는 파라미터로 RDB의 WHERE 절과 같은 기능을 하는 것으로 이해하면 된다. DL/I이 호출될 때 SSA 내에 1개 이상의 조건문장 존재 여부에 따라 Unqualified 호출과 Qualified 호출로 분류된다.
Unqualified SSAs
접근하기 원하는 세그먼트의 이름만 지정한 경우이다. 세그먼트 이름의 최대 길이는 8Byte로 끝에 1개의 공백을 추가로 붙인다. 만약 세그먼트 이름이 8Byte보다 작으면 나머지 부분은 공백으로 채운다.
형식은 아래와 같다.
다음은 COBOL 프로그램에서 구현한 Unqualified SSA의 예이다.
01 UNQUALIFIED-SSA. 05 UNQUAL-SSA-SEGMENT-NAME PIC X(08). 05 FILLER PIC X VALUE SPACE.
Qualified SSAs
특정한 값을 가진 세그먼트에 접근하기 위해서는 필드에 대한 조건문을 기술한 Qualified SSA를 사용한다. 형식은 아래와 같다.
-
세그먼트 이름
접근하려는 세그먼트의 이름을 지정한다.
-
필드 이름
조건의 비교 대상이 되는 세그먼트의 필드 이름을 지정한다. 필드 이름은 DBD 스크립트의 FIELD에 기술한 필드명과 일치해야 한다.
-
관계 연산자
지정한 필드와 검색 값 간의 관계를 나타내는 연산자를 지정한다. 연산자의 길이는 2Byte이며 지정할 수 있는 연산자는 다음과 같다.
관계 연산자 일치 (Equal to)
EQ
=□
□=
불일치 (Not equal to)
NE
^=
=^
초과 (Greater than)
GT
>□
□>
이상 (Greater than or equal to)
GE
>=
=>
미만 (Less than)
LT
<□
□<
이하 (Less than or equal to)
LE
<=
=<
□는 1Byte의 공백을 의미한다.
-
검색 값
필드명에 대응되는 값으로 지정한 값을 기준으로 하여 관계연산처리를 하게 된다.
다음은 COBOL 프로그램에서 구현한 Qualified SSA의 예이다.
01 SEGMENT-SSA. 05 FILLER PIC X(9) VALUE 'SEGMENT1('. 05 FILLER PIC X(10) VALUE 'SEG1CODE ='. 05 SEG1-SSA-CODE PIC X(3). 05 FILLER PIC X VALUE ')'.
Command Code
SSA 내의 지정된 위치에 Command Code를 설정하면 DL/I 함수의 다양한 기능을 확장하여 사용할 수 있다. Command Code는 1개의 문자로 나타내며 SSA 내의 세그먼트 이름 다음 위치인 9Byte 위치에 Command Code 지시자인 애스터리스크(*)를 설정하고 나서 10Byte 위치에 사용하기 원하는 Command Code를 설정한다.
Command Code는 Unqualified SSA와 Qualified SSA에 모두 사용할 수 있으며 사용형식은 아래와 같다.
-
Unqualified SSA Format
Unqualified SSA Format with a single Command Code -
Qualified SSA Format
Qualified SSA Format with a single Command Code
다음은 COBOL 프로그램에서 Command Code를 사용하여 Unqualified SSA를 구현한 예이다.
01 UNQUALIFIED-SSA. 05 UNQUAL-SSA-SEGMENT-NAME PIC X(08). 05 FILLER PIC X VALUE “*”. 05 UNQUAL-SSA-COMMAND-CODE PIC X VALUE “-”. 05 FILLER PIC X VALUE SPACE.
다음은 사용 가능한 Command Code의 목록이다.
코드 | 설명 |
---|---|
C |
여러 세그먼트의 키 필드 값을 연속적으로 지정한 연쇄키를 사용하여 데이터를 조회하거나 또는 삽입한다. |
D |
Path call이라고도 불리며, 계층 경로를 따라 지정한 세그먼트에 순차적으로 접근하고 접근한 모든 세그먼트의 데이터를 I/O 영역에 차례로 반환한다. |
F |
세그먼트의 첫 번째 위치를 의미하며 조회나 삽입 처리의 경우 세그먼트의 맨 처음 위치에서 지정한 작업을 수행한다. 즉, get next의 경우 get unique처럼 동작한다. |
L |
세그먼트의 마지막 위치를 의미하며 조회나 삽입 처리의 경우 세그먼트의 맨 마지막 위치에서 지정한 작업을 수행한다. |
*M |
Subset 포인터를 다음 세그먼트 인스턴스로 이동시킨다. |
N |
REPL를 호출하는 경우 사용되는 Command Code로 D Command Code에 의해 path call로 조회된 데이터의 갱신 방지를 목적으로 사용된다. |
P |
특정 세그먼트에 parentage를 설정하여 GNP를 호출하는 경우 사용할 수 있도록 한다. 일반적으로 접근한 세그먼트 중 최하위 레벨의 세그먼트가 parentage로 설정되나 P Command Code를 사용하여 그보다 상위 레벨의 세그먼트를 parentage로 설정할 수 있다. P command code를 사용한 get 요청이 실패할 경우에도 P command code가 지정된 세그먼트 레벨까지의 검색이 성공하면 그 레벨을 parentage로 설정한다. |
Q |
조회한 세그먼트의 내용을 다른 프로그램에서 갱신하는 것을 방지하는 목적으로 쓰인다. |
*R |
첫 번째 subset이 가리키는 세그먼트 데이터를 조회한다. |
*S |
현재 위치를 무조건적으로 subset 포인터에 설정한다. |
U |
현재의 세그먼트 위치를 유지시킨다. 세그먼트를 조회할 경우 원하는 데이터가 나오거나 더 이상의 데이터가 존재하지 않을 때까지 현재 세그먼트 위치가 계층구조에 따라 움직이게 되나 U Command Code를 지정한 세그먼트는 현재 위치를 유지한다. |
V |
U Command Code와 기본적으로 동일한 기능을 하나 V Command Code를 지정한 세그먼트의 상위 레벨 세그먼트의 위치도 유지시킨다. |
*W |
Subset 포인터가 아직 설정되지 않은 경우 현재위치로 설정한다. |
*Z |
Subset 포인터를 0으로 초기화하여 재사용될 수 있도록 한다. |
― |
Null Command Code로 Command Code를 하이픈(-)으로 설정하게 되면 Unqualified SSA로 처리한다. 프로그램 중간에 Command Code를 재설정하여 원하는 작업을 처리할 수도 있다. |
애스터리스크(*)가 붙은 코드는 DEDB에서만 사용된다. |
다음의 표는 Command Code별로 사용 가능한 DL/I 함수를 정리한 것이다.
GU/GHU | GN/GHN | GNP/GHNP | REPL | ISRT | DLET | |
---|---|---|---|---|---|---|
C |
○ |
○ |
○ |
− |
○ |
− |
D |
○ |
○ |
○ |
− |
○ |
− |
F |
○ |
○ |
○ |
− |
○ |
− |
L |
○ |
○ |
○ |
○ |
○ |
− |
M |
○ |
○ |
○ |
○ |
○ |
− |
N |
− |
− |
− |
○ |
− |
− |
P |
○ |
○ |
○ |
− |
○ |
− |
Q |
○ |
○ |
○ |
− |
○ |
− |
R |
○ |
− |
− |
− |
− |
− |
S |
○ |
○ |
○ |
○ |
○ |
− |
U |
○ |
○ |
○ |
− |
○ |
− |
V |
○ |
○ |
○ |
− |
○ |
− |
W |
○ |
○ |
○ |
○ |
○ |
− |
Z |
○ |
○ |
○ |
○ |
○ |
○ |
― |
○ |
○ |
○ |
○ |
○ |
○ |
다중 조건 문장
SSA 내에서 Boolean 연산자를 각 조건문 사이에 넣어 여러 개의 조건문들을 연결하여 사용할 수 있다.
관계 | 연산자 |
---|---|
AND (2개 이상의 조건에 만족하는 경우) |
'&' 또는 '*' |
OR (1개 이상의 조건에 만족하는 경우) |
'│' 또는 '+' |
다음은 COBOL 프로그램에서 다중 조건 문장을 사용한 SSA를 구현한 예이다.
01 SEGMENT1-SSA. 05 FILLER PIC X(9) VALUE ‘SEGMENT1(‘. 05 FILLER PIC X(10) VALUE ‘SEG1CODE>=‘. 05 SEG1-SSA-LOW-CODE PIC X(3). 05 FILLER PIC X VALUE ‘&‘. 05 FILLER PIC X(10) VALUE ‘SEG1CODE<=‘. 05 SEG1-SSA-HIGH-CODE PIC X(3). 05 FILLER PIC X VALUE ‘)‘.