기본 프로그래밍

tbESQL/COBOL 프로그램의 문법과 실행 과정, 런타임 에러(runtime error) 처리, 그리고 tbESQL/COBOL 문장의 실행, 커서를 설명합니다.

개요

본 절에서는 tbESQL/COBOL 프로그램의 문법과 런타임 에러 처리에 대해서 설명합니다.

tbESQL/COBOL 프로그램 문법

tbESQL/COBOL 프로그램의 문법은 다음과 같습니다.

  • SQL 문장의 시작과 끝

    • tbESQL/COBOL 프로그램에 포함되는 SQL 문장은 항상 EXEC SQL로 시작되며 END-EXEC.로 끝 난다.

    • 하나의 SQL 문장은 여러 줄에 걸쳐 있을 수 있습니다.

  • DECLARE 영역

    • DECLARE 영역은 'BEGIN DECLARE SECTION'으로 시작되며, 'END DECLARE SECTION'으로끝난다.

    • DECLARE 영역에는 변수 선언 이외에 다른 코드가 삽입되어서는 안 됩니다.

    • SQL 문장과 함께 사용되는 입/출력 변수는 항상 DECLARE 영역에 선언해야 합니다. 입/출력 변수가 구조체나 배열의 형태로 선언된 경우에도 DECLARE 영역에 선언해야 합니다. 단, 프리컴파일러 옵션에 따라 그렇지 않은 경우도 있습니다. 프리컴파일러 옵션에 대해서는 “tbESQL/COBOL 프리컴파일러 옵션”을 참고합니다.

    • 입/출력 변수가 아닌 일반적인 프로그램 변수의 경우에는 DECLARE 영역 밖에 선언되어도 무방합니다.

    • 다음은 DECLARE 영역의 예입니다.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 OPERATION PIC X(20) VARYING OCCURS 5 TIMES.
01 TELLER.
    03 EMPNO PIC S9(7).
    03 ENAME PIC X(10).
    03 SALARY PIC S9(5).
01 CNT PIC S9(9).
EXEC SQL END DECLARE SECTION END-EXEC.
  • 문자열

    • COBOL 프로그래밍 코드에 포함된 문자열은 큰따옴표(" ")를 사용합니다.

    • tbESQL/COBOL 문장에 포함되는 문자열은 작은따옴표(' ')를 사용합니다.

  • 주석(Comment)

    • 주석은 COBOL 프로그래밍 언어에서 사용하는 방법 이외에 두 개의 마이너스 부호(--)를 이용하는 방 법이 있습니다.

    • 두 개의 마이너스 부호(--)를 사용하는 주석은 부호(--)가 시작되는 곳에서부터 그 라인의 끝까지 주석 으로 처리합니다. 또한 EXEC SQL 문장에만 사용될 수 있으며, COBOL 프로그래밍 코드 부분에는 사용되지 못합니다.

다음은 주석을 사용하는 예입니다.

프로그램 실행 과정

tbESQL/COBOL 프로그램을 작성할 때는 필요한 데이터 타입이나 함수 프로토타입 등을 이용하기 위해서 반드시 SQLCA 파일을 포함해야 합니다. 즉, 아래의 내용이 항상 tbESQL/COBOL 프로그램 소스 코드의 맨 위에 명시되어 있어야 합니다.

만약 존재하지 않으면 프리컴파일러 실행 후에 생성되는 COBOL 코드에 자동으로 추가됩니다.

다음 그림은 tbESQL/COBOL 프로그램 소스 코드를 실행 파일로 생성하기 위해 거치는 전 과정입니다.

프리 컴파일 과정을 제외하면 COBOL 프로그램의 경우와 별로 다르지 않습니다.

[그림 1] tbESQL/COBOL 프로그램 실행 과정

img

위의 [그림 1]의 과정을 순서대로 설명하면 다음과 같습니다.

  1. tbESQL/COBOL program tbESQL/COBOL 프로그램을 작성한 뒤 소스 코드를 저장하면 .tbco 확장자를 갖는 파일이 생성됩니다.

  2. Precompile 작성된 프로그램을 실행하려면, 먼저 프리컴파일 과정을 거쳐야 합니다. tbESQL/COBOL의 프리컴파일 러를 실행하는 명령어는 tbpcb입니다. 다음은 emp.tbco 프로그램 파일에 대해 프리컴파일을 실행하는 예입니다.

[예 1] emp.tbco 프로그램의 프리컴파일

프리컴파일러를 실행하는 명령어는 옵션을 포함할 수 있습니다.

다음은 프리컴파일러 옵션을 사용하여 COPY 또는 SQLCA ESQL INCLUDE 파일의 경로를 지정하는 예입니다.

[예 2] 프리컴파일러 옵션을 사용한 COPY 또는 SQLCA ESQL INCLUDE 파일의 경로 지정

프리컴파일러 옵션에 대한 자세한 내용은 “tbESQL/COBOL 프리컴파일러 옵션”을 참고합니다.

  1. General program 프리컴파일의 결과로는 COBOL 프로그램 소스 코드가 생성되며, 이때 파일의 이름은 원본 파일의 이 름과 동일하고 확장자만 .cob로 변경됩니다. 예를 들어 emp.tbco 파일을 프리컴파일하면 emp.cob라는 이름을 가진 파일이 생성됩니다.

  2. Compile, Link 프리컴파일이 완료된 파일은 그 다음으로 컴파일 과정과 링크 과정을 거쳐야 합니다. [그림 1]에서는 컴 파일과 링크 과정이 따로 표현되었지만, 실제로는 대개의 경우에 두 과정이 함께 수행됩니다.

다음은 [예 1]의 실행결과로 생성된 emp.cob 파일을 컴파일하고 링크하는 예입니다. 본 예제는 64-bit 머신의 MF-COBOL 컴파일러를 사용하는 경우입니다.

[예 3] 컴파일과 링크 과정

tbESQL/COBOL에서는 tbCLI 함수도 함께 사용하기 때문에 tbERTL 라이브러리 이외에 tbCLI 라이브 러리를 함께 링크합니다.

위의 [그림 1]에서 링크(Link) 과정에서 링커(Linker)의 입력으로 받아들이는 tbERTL 라이브러리는 tbESQL/COBOL의 함수 라이브러리입니다. 이 라이브러리에는 esql_do 함수 등이 정의되어 있으며, tbESQL/COBOL 프로그램을 안전하고 효율적으로 실행하기 위한 여러 가지 작업을 수행합니다.

  1. Execution code 컴파일 과정과 링크 과정을 거치고 나면 emp라는 이름의 실행 파일이 생성됩니다.

런타임 에러 처리

tbESQL/COBOL 프로그램 내의 SQL 문장을 실행했을 때 에러 또는 경고 등의 여러 가지 예외 상황이 발생할 수 있습니다. 예를 들면 SELECT 문장의 실행 결과로 반환되는 로우가 존재하지 않거나 특정 컬럼의 일 부 내용이 잘린 경우를 들 수 있습니다. tbESQL/COBOL 프로그램 내에서는 에러 또는 경고 상황이 발생한 경 우 그에 대한 적절한 처리를 프로그램 내에서 수행할 수 있습니다.

tbESQL/COBOL에서는 이러한 런타임 에러 처리를 위해 다음의 세 가지 인터페이스를 지원합니다.

인터페이스
설명

상태 변수

  • 상태 변수(Status Variable)는 임의의 SQL 문장이 실행된 결과가 저장되는 변수

  • 프로그램 내에서는 SQL 문장을 실행한 후에 상태 변수의 값을 검토하여, 에러 또는 경고 상황의 발생을 알 수 있고, 그에 따른 처리를 수행할 수 있음

SQLCA

  • SQLCA(SQL 통신 영역: SQL Communication Area)는 임의의 SQL 문장이 실행된 결과가 저장되는 구조체 변수

  • 이 구조체는 SQLCA라는 이름으로 SQLCA ESQL INCLUDE 파일에 정의되어 있으며, 상태 변수를 포함하고 있음

  • 상태 변수와 마찬가지로, SQL 문장을 실행한 후에 SQLCA 내의 적절한 멤버 변수의 값을 검토하여 에러 또는 경고 상황의 발생을 알 수 있고, 그에 따른 처리를 수행할 수 있음

WHENEVER

  • WHENEVER 문장은 에러 또는 경고 상황이 발생하면 미리 정해진 특정 동작을 수행

  • 상태 변수나 SQLCA 구조체를 이용하면 SQL 문장을 실행할 때마다 에러 또는 경고 상황이 발생하였는지 검토해야 함

  • 하지만 WHENEVER 문장 을 사용하면 tbESQL/COBOL이 자동으로 예외 상황을 검토하고 그에 따른 처리를 수행

프로그램 구조

tbESQL/COBOL 프로그램의 구조는 다음과 같습니다.

  • 변수 선언

  • 초기화

  • 데이터베이스 작업

  • 종료화

  • 에러 처리

변수 선언

변수 선언 부분에는 “구성요소”에서 설명한 DECLARE 영역이 포함됩니다. tbESQL/COBOL 문장에서 데이터베이스 작업에 사용될 모든 변수를 DECLARE 영역에 선언해야 합니다. 데이터베이스 작업과 관련이 없는 변수는 DECLARE 영역에 포함하지 않아도 됩니다.

다음은 변수 선언의 예입니다.

초기화

초기화 부분에서는 다음의 두 가지를 수행합니다.

  • 런타임 에러가 발생했을 때 어떤 작업을 수행할 것인지 선언합니다.

런타임 에러가 발생했을 때 수행하는 작업에는 에러 처리 함수를 호출하는 경우, 에러를 무시하고 프로 그램을 계속 진행하는 경우, 프로그램을 종료하는 경우, 특정 위치로 이동한 후 실행을 계속하는 경우 등이 있습니다. 대부분의 경우에 에러 처리를 위한 함수를 미리 정의하고 그 정의된 함수를 호출합니다.

다음은 런타임 에러가 발생했을 때 tbesql_error 함수를 호출하는 예입니다.

[예 4] tbesql_error함수 호출

  • Tibero의 데이터베이스에 접속합니다.

데이터베이스에 접속할 때는 반드시 사용자 이름과 패스워드를 함께 명시해야 합니다.

다음의 소스 코드는 USERNAME과 PASSWORD, 이렇게 두 개의 입력 변수를 이용해 데이터베이스에 접속하는 예입니다.

[예 5] 입력 변수를 이용해 데이터베이스에 접속

데이터베이스 작업

데이터베이스 작업 부분에서는 tbESQL/COBOL 문장을 사용해 데이터베이스 질의 및 갱신을 수행합니다. 이 부분은 tbESQL/COBOL 프로그램에서 가장 중요한 부분 중 하나입니다.

데이터베이스와 관련된 작업에는 입력 변수와 출력 변수를 많이 사용하게 됩니다. 데이터베이스 질의와 관 련된 소스 코드에는 커서를 선언하고, 이 선언된 커서를 이용해 로우를 액세스하는 코드가 포함됩니다.

다음은 데이터베이스 작업 부분의 예입니다.

종료화

종료화 부분에서는 모든 데이터베이스 작업을 마치고 커밋을 수행하거나 롤백을 수행합니다.

circle-exclamation

다음은 데이터베이스에 부분 롤백을 수행한 뒤 커밋을 하는 예입니다.

에러 처리

에러 처리 부분에서는 에러를 처리하기 위한 코드가 포함됩니다. 에러 처리와 관련된 코드는 다른 코드와 섞 여 동일한 하나의 함수 안에 포함될 수도 있으며, 별도의 함수로 정의할 수도 있습니다.

다음은 에러 처리의 예입니다.

tbESQL/COBOL 문장 실행

본 절에서는 tbESQL/COBOL 프로그램에서 SELECT, INSERT, UPDATE, DELETE 문장을 실행하는 방 법에 대해 설명합니다. 각 문장에는 입/출력 변수가 사용되는데, 입/출력 변수는 각 문장 내에 포함된 스키마 객체와 구별하기 위하여 반드시 앞에 콜론**(:)**이 와야 합니다.

SELECT

SELECT 문장은 데이터베이스에 질의를 수행하고 결과 로우를 반환하는 문장입니다. 결과 로우의 개수는 보통 하나 이상이지만 하나도 없을 수도 있습니다.

INTO절과 출력 변수

tbESQL/COBOL 프로그램 내에서 사용되는 SELECT 문장은 일반 SELECT 문장과 같은 문법을 가진다. 다만 SELECT 리스트 다음에 결과 로우의 각 컬럼 값을 출력 변수에 저장하기 위해 INTO 절이 삽입됩니다.

다음은 SELECT 문장의 INTO 절에 출력 변수가 사용된 예입니다.

다음은 SELECT문장의 INTO 절에 포함되는 출력 변수에 대한 설명입니다.

  • 컬럼 값과 출력 변수의 대응 INTO 절에 포함되는 출력 변수는 SELECT 리스트 내의 컬럼과 같은 개수이어야 하며, 지시자 변수와 함께 사용될 수 있습니다. 질의 결과로 반환된 로우의 각 컬럼 값은 컬럼 값과 동일한 순서로 대응되는 각각 의 출력 변수에 저장됩니다. 출력 변수에 저장될 때 tbESQL/COBOL 프로그램에서는 필요한 경우 데이터 타입의 변환을 수행합니다.

  • 구조체 변수 INTO 절에 포함되는 출력 변수에는 구조체 변수를 사용할 수도 있습니다. 이때 구조체 변수에 포함된 멤버 변수의 개수는 SELECT 리스트 내의 컬럼과 개수가 같아야 합니다. tbESQL/COBOL 프로그램에서는 결 과 로우의 각 컬럼 값을 구조체 변수 내의 각 멤버 변수에 할당합니다.

  • 로우의 개수에 따른 출력 변수 SELECT 문장의 결과 로우의 개수가 반드시 하나라는 보장이 있습니다면 INTO 절에 단순 출력 변수를 이용 하여 처리가 가능합니다. 하지만 하나 이상인 경우에는 커서를 사용하거나 INTO 절에 출력 배열 변수를 사용해야 합니다.

circle-info

참고 커서에 대한 자세한 내용은 “커서”와 “스크롤 가능 커서”를, 배열 변수에 대한 자세한 내용은“배열 변수”를 참고합니다.

다음은 결과 로우가 하나인 경우 이를 처리하는 예입니다.

위의 예에서 컬럼 EMPNO가 테이블 EMP의 기본 키 컬럼이므로 질의 결과 로우의 개수가 하나라는 것을 알 수 있습니다.

WHERE 절과 입력 변수

SELECT 문장 내에서 변수의 위치는 INTO 절에 출력 변수가 포함되는 것 외에 WHERE 절에 입력 변수가 포함됩니다.

다음은 SELECT 문장의 WHERE 절에 입력 변수가 사용된 예입니다.

다음은 SELECT 문장의 WHERE 절에 포함되는 입력 변수에 대한 설명입니다.

  • 입력 변수의 값 설정 WHERE 절에 포함되는 입력 변수의 값은 SELECT 문장이 실행되기 전에 설정되어 있어야 합니다. 그 이 유는 SELECT 문장은 실행 직전에 입력 변수의 값을 가져와서 SELECT 문장을 완성한 뒤에 실행되기 때문입니다. SELECT 문장의 실행에 필요한 입력 변수의 값은 그 문장이 실행되기 직전에 읽혀지므로, 입 력 변수의 값은 프로그램 실행 중에 동적으로 설정할 수 있습니다.

  • 입력 변수 사용의 제약 SELECT 문장의 입력 변수는 상수를 대신하여 사용할 수 있지만, 스키마 객체 또는 컬럼 등의 이름을 대신하여 사용될 수는 없습니다. SELECT 문장에 부질의(Subquery)가 사용되는 경우에는 부질의 내에 출력 변수를 포함시킬 수는 없지만 입력 변수를 포함시킬 수는 있습니다.

다음은 컬럼의 이름을 대신하여 입력 변수가 사용된 예입니다.

위의 예에서 WHERE 절 다음에 컬럼의 이름이 나와야 하는데, 대신 변수가 사용되었기 때문에 잘못되었 다.

INSERT

INSERT, DELETE, UPDATE 문장은 공통적으로 질의의 결과 로우가 존재하지 않으므로 출력 변수 없이 입력 변수만을 사용합니다. INSERT 문장에서 입력 변수는 컬럼에 삽입할 데이터 값의 위치나 부질의 내부 에 사용될 수 있습니다.

INSERT 문장에서 삽입하고자 하는 컬럼 값의 일부에 대해서만 입력 변수를 사용할 수도 있습니다. 다음은 일부 컬럼에 대해서만 입력 변수를 사용하는 예입니다.

삽입하고자 하는 모든 컬럼 값에 대하여 입력 변수를 사용하는 경우 구조체 변수를 사용할 수 있습니다. 이때 구조체 변수에 포함된 각 변수 값은 삽입하고자 하는 각 컬럼 값에 대응됩니다.

다음은 구조체 변수를 사용해 데이터를 삽입하는 예입니다.

또한 부질의에 입력 변수를 사용할 수도 있습니다. 다음은 부질의를 포함하는 INSERT 문장의 예입니다.

UPDATE

UPDATE 문장도 INSERT 문장과 마찬가지로 입력 변수만을 사용합니다.

UPDATE 문장에서는 SET 절의 컬럼 값의 위치나 WHERE 절에서 입력 변수가 사용될 수 있습니다. UPDATE 문장에 포함된 부질의에서도 입력 변수를 사용할 수 있습니다. UPDATE 문장에서는 INSERT 문장에서와 달 리 구조체 입력 변수를 사용할 수 없습니다.

다음은 일부 컬럼 값과 WHERE 절 내에 입력 변수를 사용하는 예입니다.

다음은 부질의에 입력 변수를 사용하는 예입니다.

DELETE

DELETE 문장도 INSERT, UPDATE 문장과 마찬가지로 입력 변수만을 사용합니다. DELETE 문장에서는 WHERE 절에서 입력 변수가 사용됩니다. DELETE 문장에서도 UPDATE 문장과 마찬가지로 구조체 입력 변수를 사용할 수 없습니다.

다음은 입력 변수를 사용하는 DELETE 문장의 예입니다.

커서

본 절에서는 커서의 기본적인 사용 방법에 대하여 설명하고, 갱신 및 삭제를 위한 CURRENT OF 절을 설 명합니다. 그리고 마지막으로 사용 예제를 제시합니다.

SELECT 문을 통한 질의를 수행할 때 WHERE 절에 기본 키 제약조건을 부여하지 않으면, 대개의 경우 결 과 로우의 개수는 하나 이상입니다. 커서는 이렇게 반환된 다수의 결과 로우에 각각 차례로 액세스하기 위한 데이터 구조입니다.

다음은 커서를 사용하는 순서입니다.

  1. 커서를 사용하기 위해서는 DECLARE CURSOR를 사용해 맨 먼저 SQL 문장과 연관하여 커서를 선언 해야 합니다. 커서를 선언할 때에는 항상 커서의 이름을 주어야 하며, 커서의 선언부는 그 커서를 사용하 는 다른 모든 문장의 앞에 와야 합니다.

다음은 EMP-CURSOR라는 이름으로 커서를 선언하는 예입니다.

[예 6] 커서의 선언

  1. 커서를 사용하기 위해서는 OPEN을 사용해 해당 커서를 열어야 합니다.

OPEN을 실행하면 연관된 SELECT 문장이 실행되어 질의의 결과 로우가 반환됩니다. 또한 커서는 결과 로우 중에서 맨 처음에 위치한 로우의 직전을 가리킨다. 첫 FETCH가 실행되면 첫 번째 로우를 가리키 게 됩니다. OPEN을 실행할 때 유의할 점은 커서를 선언할 때 SELECT 문장에 포함된 입력 변수의 값은 OPEN이 실행될 때 할당됩니다는 것입니다.

다음은 [예 6]에서 선언한 EMP-CUROSR라는 이름의 커서에 OPEN을 실행하는 예입니다.

[예 7] OPEN의 실행

  1. FETCH를 실행해 로우에 액세스를 합니다.

OPEN의 실행으로는 아직 로우에 액세스를 할 수 있는 것은 아니다. 로우에 액세스를 하기 위해서는

FETCH를 실행해야 합니다. FETCH의 INTO 절에는 구조체 변수나 지시자 변수를 함께 사용할 수 있습니다. 다음은 FETCH를 실행하는 예입니다.

[예 8] FETCH의 실행

FETCH를 실행하면 먼저 커서가 다음 결과 로우를 가리키게 되고, 커서가 가리키는 결과 로우를 출력 변수에 저장합니다. FETCH를 실행할 때마다 커서는 다음 결과 로우를 가리키고, 결국 맨 마지막 결과 로 우의 범위를 넘어 FETCH를 실행하면, NOT FOUND 에러가 발생합니다.

대개의 경우 FETCH를 무한 루프 안에 포함시키며, NOT FOUND 에러가 발행하면 루프를 빠져 나오도 록 코드를 작성합니다. 이때 NOT FOUND 에러가 발생했을 때 루프를 빠져 나오도록 하기 위해서는 WHENEVER 문장을 사용합니다.

다음은 WHENEVER 문장을 사용하는 예입니다.

[예 9] WHENEVER 문장의 사용

WHENEVER 문장에 GOTO 명령 이외에 DO CALL, DO PERFORM 등의 명령을 사용할 수도 있습니다.

OPEN을 사용해 커서를 열기 전이나 CLOSE를 사용해 커서를 닫은 후 또는 NOT FOUND 에러가 발생 한 이후에 FETCH를 실행하면 에러가 발생합니다.

FETCH를 이용해 다음 로우 뿐만 아니라 이전 로우를 액세스할 수도 있습니다. 이러한 작업을 위해서는 스 크롤 가능 커서를 선언해야 합니다. 스크롤 가능 커서에 대해서는 “스크롤 가능 커서”를 참고합니다.

  1. 커서 사용의 마지막 단계는 CLOSE를 사용해 커서를 닫는 것입니다. 커서를 닫은 이후에는 그 커서에 대 해 어떠한 작업도 실행할 수 없습니다.

다음은 EMP-CURSOR라는 이름의 커서에 CLOSE를 실행하는 예입니다.

[예 10] CLOSE의 사용

CURRENT OF 절

커서를 이용해 SELECT 문장의 실행 결과 로우를 차례로 액세스하면서 커서가 현재 가리키고 있는 결과 로우를 삭제하거나 갱신하려고 할 때 DELETE 문장과 UPDATE 문장에 CURRENT OF 절을 사용합니다.

SELECT 문장에서 CURRENT OF 절을 사용하기 위해서는 FOR UPDATE 절을 포함해야 합니다. FOR UP DATE 절은 질의 결과로 반환된 로우에 잠금(LOCK)을 설정합니다. 잠금이 설정된 로우는 현재 트랜잭션이 커밋 또는 롤백되기 전까지는 다른 트랜잭션이 로우를 갱신하거나 삭제할 수 없습니다.

다음은 UPDATE 문장에서 CURRENT OF 절을 이용하여 컬럼 SALARY만을 갱신하는 예입니다.

커서가 현재 가리키고 있는 로우는 FETCH 문장을 실행하여 방금 전에 컬럼 값을 읽은 로우입니다. 커서에 대해 OPEN 문장을 실행한 후에 한번도 FETCH 문장을 실행하지 않았거나 모든 결과 로우를 읽고 나서 NOT FOUND 에러가 반환되었습니다면 커서가 현재 가리키고 있는 로우는 없습니다.

현재 가리키고 있는 로우가 없는 커서를 이용하여 DELETE 또는 UPDATE 문장을 실행하였습니다면 에러를 반환합니다. 또한 OPEN 문장을 수행하지 않았거나 CLOSE 문장을 이미 수행한 커서를 이용하여 삭제 또는 갱신을 시도할 때에도 에러를 반환합니다.

CLOSE_ON_COMMIT 옵션이 'YES'로 지정된 경우를 제외하고는 일반적으로 커서는 현재 트랜잭션이 커 밋 또는 롤백한 후에도 사용할 수 있습니다. 즉, 커서를 이용하여 질의 결과 로우를 액세스할 수 있습니다. 하지만 FOR UPDATE 절을 포함한 SELECT 문장에 대한 커서는 사용할 수 없습니다. 왜냐하면 트랜잭션이 커밋되거 나 롤백되는 동시에 결과 로우에 설정되었던 잠금을 해제해 버리기 때문입니다.

사용 예제

다음은 커서를 사용하는 예제 프로그램입니다.

[예 11] 커서의 사용

① tbESQL/COBOL 문장 내에 포함되는 모든 입/출력 변수는 DECLARE 영역 안에서 선언합니다. 프로그램 의 맨 앞쪽에서 커서를 선언하고 있지만, 변수의 선언과는 달리 커서의 선언은 어떠한 위치에 오더라도 상 관없으며, 그 커서가 사용되기 전에만 선언되면 됩니다.

②, ④ 두 개의 커서를 선언합니다. 각각 단순 질의와 갱신을 위한 커서인데, 단순 질의를 위한 커서는 EMP- CURSOR이고, 갱신을 위한 커서는 EMP-UPDATE-CURSOR입니다.

③, ⑤ 변수 DEPTNO가 두 개의 커서에 공통적으로 사용됩니다. 커서와 연관된 SELECT 문장은 OPEN 문 장으로 커서를 열 때 실행되며, 그 직전에 입력 변수의 값을 읽어 들인다. 따라서 같은 변수를 사용하더라 도 각각의 SELECT 문장이 실행될 때 서로 다른 DEPTNO 값이 적용될 수도 있습니다.

⑥ 프로그램의 맨 마지막에서는 현재 트랜잭션을 커밋합니다. 단순 질의를 위한 커서 EMP-CURSOR는 트 랜잭션 커밋 후에도 계속 사용할 수 있으나, 갱신을 위한 커서 EMP-UPDATE-CURSOR는 사용할 수 없습니다.

스크롤 가능 커서

본 절에서는 스크롤 가능 커서(Scrollable Cursors)의 사용 방법을 설명하고, 사용 예제를 제시합니다.

사용 방법

커서는 질의의 결과 로우를 액세스할 때 항상 다음에 위치한 로우만 액세스할 수 있는 것에 비해, 스크롤 가능 커서는 임의의 로우에 액세스를 할 수 있습니다. 예를 들어 스크롤 가능 커서는 현재 커서가 가리키고 있 는 로우의 바로 이전 로우를 액세스하거나 전체 결과 로우 중에서 n번째 로우를 액세스할 수 있습니다.

스크롤 가능 커서는 사용 방법의 편리성과 유연성을 제공하지만 커서와 비교했을 때 메모리 등의 리소스 를 많이 사용할 수 있으므로 프로그램의 실행 성능을 떨어뜨릴 수 있습니다. 따라서 꼭 필요한 경우가 아니라 면 커서를 사용하는 것이 효율적입니다.

다음은 커서와 스크롤 가능 커서의 차이점입니다.

커서
스크롤 가능 커서

다음 위치에 있는 로우만 차례대로 액세스

임의의 위치에 있는 로우를 액세스할 수 있음

'DECLARE {커서 이름} CURSOR'의 형태로 선언

'DECLARE {커서 이름} SCROLL CURSOR'의 형태로 선언

FETCH를 실행할 때 옵션을 지정할 수 없음

FETCH를 실행할 때 반드시 옵션을 지정해야 함

스크롤 가능 커서에서도 커서와 동일하게 OPEN과 CLOSE를 사용합니다. 스크롤 가능 커서가 현재 가리키 고 있는 로우에 대하여 삭제 및 갱신을 수행하고자 할 때에도 커서와 마찬가지로 DELETE 문장과 UPDATE 문장 내에서 CURRENT OF 절을 이용합니다. 문장의 작성 및 사용 방법은 커서와 동일합니다.

커서와 스크롤 가능 커서의 차이점을 좀더 상세하게 설명하면 다음과 같습니다.

  • 스크롤 가능 커서의 선언 스크롤 가능 커서의 선언은 SCROLL 키워드가 포함됩니다는 것을 제외하면 커서의 선언과 동일하며 다 음과 같은 형태로 선언합니다.

다음의 소스 코드는 스크롤 가능 커서를 선언하는 예입니다.

  • 스크롤 가능 커서에서의 FETCH의 사용 스크롤 가능 커서에서 FETCH를 사용할 때는 항상 액세스할 대상 로우를 지정해야 합니다. 다음은 FETCH에서 액세스를 할 대상 로우를 지정할 때 사용되는 옵션입니다.

옵션
설명

NEXT

  • 현재 커서가 가리키고 있는 로우의 다음 로우에 액세스를 함

  • PRIOR 옵션과 반대 (생략 가능)

PRIOR

  • 현재 커서가 가리키고 있는 로우의 이전 로우에 액세스를 함

  • NEXT 옵션과 반대

FIRST

  • 맨 처음에 위치한 로우에 액세스를 함

  • LAST 옵션과 반대

LAST

  • 맨 마지막에 위치한 로우에 액세스를 함

  • FIRST 옵션과 반대

CURRENT

현재 로우에 액세스를 함

RELATIVE offset

  • 현재 커서가 가리키고 있는 로우의 다음offset 번째에 위치한 로우에 액세스를 함

  • offset 값이 음수라면 커서가 현재 위치에서 앞으로 이동

  • 예를 들어 현재 커서가 8번째 로우를 가리키고 있는데, 'FETCH RELATIVE -3'을 실행한다면 커서는 5번째 로우를 가리키게 됨

ABSOLUTE offset

전체 로우 중에서 offset 번째 로우에 액세스

다음은 FETCH에 옵션을 사용하는 예입니다.

위의 예에서는 각각 순서대로 첫 번째 문장은 이전 로우를 액세스하고, 두 번째 문장은 마지막 로우를 액세스합니다. 세 번째 문장은 전체 로우 중에서 세 번째 로우를 액세스하고 있습니다. 만약 액세스하려는 로 우가 존재하지 않으면 NOT FOUND 에러가 반환됩니다.

사용 예제

다음은 스크롤 가능 커서를 사용하는 예제 프로그램입니다.

위의 예에서는 주석을 삽입하여, FETCH를 실행할 때마다 스크롤 가능 커서의 현재 위치를 설명하였습니다. 또한 질의 결과 로우가 8개 이상임을 가정합니다.

SQL 문장 내에 포함되는 모든 입/출력 변수는 DECLARE 영역 안에서 선언하였습니다. 커서를 선언할 때와 마 찬가지로 스크롤 가능 커서를 선언하는 문장도, 스크롤 가능 커서가 사용되기 전이라면 어떤 위치에 있어 도 상관없습니다.

Last updated