문제 상황
COBOL-DB2 프로그램에서 변수의 길이를 PIC X(5)에서 PIC X(8)로 늘리도록 변경했습니다. 그런데 프로그램 내 SQL 문장에는 아무런 변경이 없습니다. 이러한 변경 사항에 대해 프로그램의 PLAN/PACKAGE를 BIND하지 않고 실행하면 어떤 결과가 발생할까요?
해결 방법
변수 길이를 PIC X(5)에서 PIC X(8)로 변경하는 것은 DB2 관점에서의 변경이 아니며, 프로그램의 SQL 문장에 대해서도 별도의 수정이 필요하지 않습니다. 하지만 그럼에도 불구하고 반드시 PLAN/PACKAGE를 다시 BIND해야 합니다. 그렇지 않으면 SQL 오류 코드 -818이 발생하는데, 이 오류는 "로드 모듈에 사전 컴파일러가 생성한 타임스탬프 x가 DBRM z로부터 빌드된 BIND 타임스탬프 y와 일치하지 않습니다"라는 의미입니다.
오류 -818이 발생하는 이유
COBOL-DB2 프로그램이 실행될 때마다 로드 모듈(Load Module)과 패키지/DBRM의 타임스탬프가 서로 비교됩니다. 프로그램에서 변수 길이를 변경하고(SQL 변경은 없음) 컴파일을 수행하면, 로드 모듈에는 새로 생성된 타임스탬프가 기록됩니다. 반면 이 시점에 BIND를 수행하지 않으면 패키지/DBRM에는 여전히 이전 타임스탬프가 남아 있게 됩니다.
결국 이 프로그램을 실행하면 두 타임스탬프가 일치하지 않기 때문에, 해당 프로그램을 호출하는 JCL 스텝이 SQL 오류 코드 -818과 함께 실패하게 됩니다.
LEVEL 옵션을 활용한 예외 처리
만약 SQL 문장이 향후 절대 변경되지 않을 것이 확실한 COBOL-DB2 프로그램이라면, 사전 컴파일(Precompile) 시점에 LEVEL 옵션을 사용할 수 있습니다. 이 옵션을 사용하면 타임스탬프 검증 방식이 달라져, SQL 변경이 없는 한 재컴파일 후에도 기존 BIND를 그대로 사용할 수 있습니다.
아래는 LEVEL 옵션을 적용한 BIND 스텝의 예시입니다.
예제
//BIND EXEC PGM=IKJEFT01
//STEPLIB DD DSN=DIS.TEST.LOADLIB,DISP=SHR
//SYSOUT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(TB3)
BIND PLAN(PLANA) -
PKLIST(PACKA) -
LEVEL -
ACQUIRE(ALLOCATE) -
ISOLATION (RS)
/*
정리
SQL 문장에 변경이 없더라도 프로그램을 다시 컴파일했다면 반드시 재BIND를 수행해야 합니다. 그렇지 않으면 로드 모듈과 DBRM 간의 타임스탬프 불일치로 인해 SQL 오류 -818이 발생하여 프로그램 실행이 실패합니다. 다만 SQL 변경이 전혀 없을 것이 보장되는 프로그램이라면 LEVEL 옵션을 통해 이러한 제약을 피할 수 있습니다.