SQL에 대한 open 고려사항

SQL의 컨텍스트에서 EGL open 문은 관계형 데이터베이스로부터 결과 세트를 작성하고 목록을 통해 이동하는 데 사용할 수 있는 커서를 작성합니다.

EGL은 이 커서에 대한 직접 액세스를 제공하지 않지만 대신 get 문과 함께 위치 옵션을 제공합니다(SQL에 대한 get 고려사항 참조). open 문이 실행된 후 커서는 결과 세트의 첫 번째 행(레코드)을 가리킵니다.

구문

open 문의 구문 다이어그램
resultSetID
open 문이 작성하는 결과 세트를 식별하기 위해 사용자가 선택한 문자열입니다. ID를 위치 get 문과 함께 사용하거나 replace, delete 또는 close 문과 함께 사용할 수 있습니다.
rowsetsize
RowsetSize는 복수 행 삽입 1회 복수 행 페치 1회에서 검색되는 행 수를 제어하는 어노테이션입니다.
scroll
위치 get 문으로 결과 세트를 통해 이동할 수 있게 해주는 옵션입니다. 위치 get 문에 대한 자세한 정보는 SQL에 대한 get 고려사항의 내용을 참조하십시오. 이 옵션은 Java™에서 출력을 생성하는 경우에만 사용 가능합니다.
hold
커미트가 발생할 때 프로그램이 결과 세트에서 위치를 유지하게 하는 옵션입니다. hold 옵션은 다음 조건이 모두 참인 경우에 적절합니다.
  • 스토어드 프로시저를 호출하지 않고 EGL open 문을 사용하여 커서를 엽니다.
  • 결과 세트에서 위치를 잃지 않고 주기적으로 변경사항을 커미트하려 합니다.
  • 데이터베이스 관리 시스템은 SQL 커서 선언에서 WITH HOLD 옵션의 사용을 지원합니다.

hold 옵션이 지정된 커서는 커미트 시 닫히지 않습니다. 그러나 롤백 또는 데이터베이스 연결은 모든 커서를 닫습니다. 커미트 시 커서 위치를 유지할 필요가 없으면 hold를 지정하지 마십시오.

자세한 정보는 이 주제의 "호환성"을 참조하십시오.

forUpdate
EGL 문이 데이터베이스에서 검색한 데이터를 나중에 대체하거나 삭제할 수 있도록 하는 옵션입니다. 스토어드 프로시저를 호출하는 경우에는 이 옵션을 사용하지 마십시오.
usingKeys ... field
여기에서 SQL 레코드의 필드 이름을 지정하여 레코드 정의에서 지정한 키 필드를 대체할 수 있습니다. usingKeys 절로 지정하는 필드는 암시적 SQL 문에 WHERE 절의 키-값 컴포넌트를 빌드합니다. 명시적 SQL문을 지정하지 않으면 런타임에 암시적 SQL문이 사용됩니다. usingKeys 절을 포함하는 경우 SQL 레코드 변수도 지정해야 합니다.

usingKeys 절을 지정하지 않으면 암시적 명령문의 키-값 컴포넌트는 open 문에서 참조되는 SQL 레코드 파트를 기반으로 합니다.

forUpdate 키워드를 지정하면 키 항목과 연관된 열이 SQL FOR UPDATE OF 절에 나열된 열에서 제외됩니다. forUpdate 키워드를 지정하지 않으면 키 항목과 연관된 열만 SQL ORDER BY 절의 열 목록에 포함됩니다.

그렇지 않으면 EGL이 생성할 수 있는 모든 암시적 코드는 임베디드 SQL문을 지정하면 무시됩니다.

with #sql{ sqlStatement }
임베디드 SQL SELECT 문을 지정합니다. 이 명령문은 SQL 레코드 변수도 지정하는 경우 선택사항입니다. 임베디드 코드는 그렇지 않으면 EGL이 생성할 수 있는 모든 암시적 코드보다 우선순위가 높습니다. #sql 지시문과 왼쪽 중괄호 사이에 공백을 남기지 마십시오.
코드에 SQL 레코드를 사용하고 명시적 SQL을 포함하며 INTO 절이 없는 get 또는 open 문이 있는 경우를 고려하십시오. 예를 들어, 이러한 get 문을 포함하는 다음과 같은 EGL 코드가 있습니다.
customer CustomerRecordPart{};
get customer with #sql{
   select MySCHEMA.CUSTOMER.Column01
   from MYSCHEMA.CUSTOMER
   where MYSCHEMA.Column02 = "AZ"}; 
해당 코드에서 참조되는 레코드 파트는 다음과 같습니다.
Record CustomerRecordPart type SQLRecord {tableNames = [["MYSCHEMA.CUSTOMER"]]}
   customerNumber INT    {column = "MYSCHEMA.CUSTOMER.Column01"};
   ...
end

방금 설명한 get 또는 open 문에서 SQL SELECT 절의 열 이름에 사용된 규정은 레코드 파트의 해당 필드에 사용된 규정과 일치해야 합니다.

into target
결과 세트에서 값을 수신하는 EGL 호스트 변수(호스트 변수 참조)를 식별하는 SQL INTO 절에 해당합니다. 또는 EGL이 레코드의 모든 필드를 사용하는 경우 레코드 이름을 지정할 수도 있습니다. #sql 지시문 외부에 있는 이러한 절에서는 호스트 변수의 이름 앞에 콜론을 포함하지 마십시오.
preparedStatementID
EGL prepare 문으로 작성된 코드를 식별하며, 동적 처리를 허용합니다. 세부사항은 SQL에 대한 prepare 고려사항의 내용을 참조하십시오.
using field
런타임에 준비된 명령문이 사용할 수 있는 EGL 호스트 변수를 식별하는 SQL USING 절에 해당합니다. #sql 지시문 외부에 있는 using field 절에서는 호스트 변수 이름 앞에 콜론을 포함하지 마십시오.
SQLRecordVariable
SQL 레코드 변수의 이름입니다. SQL 레코드 변수를 지정하지 않는 경우, 임베디드 SQL 코드를 #sql 지시문과 함께 제공해야 합니다. SQL 레코드 변수를 제공하고 임베드된 SQL 코드를 지정하지 않으면 EGL은 레코드 특성의 정보를 사용하여 암시적 SQL SELECT 문을 작성합니다. open 조작 다음에 변수를 조회하여 오류 조건을 발견할 수 있습니다. 자세한 정보는 이 주제의 "오류 조건"을 참조하십시오.
SQLDynamicArray
이 변수는 SQL 레코드 변수로 구성된 동적 배열의 이름을 지정합니다. EGL은 SQLRecord의 동적 배열을 open 문의 대상으로 지원합니다. 동적 배열의 사용은 이 명령문에 대해 rowset 처리를 사용 중인 경우에만 올바릅니다.

기본 처리

SQL 레코드 변수를 지정하는 경우 open 문에는 기본적으로 다음과 같은 효과가 있습니다.
  • open 문은 행 세트를 사용 가능하게 합니다. EGL은 SQL 레코드 파트에서 맵핑을 사용하여 선택된 행의 각 열을 레코드 변수 필드와 연관시킵니다. 읽기 전용 레코드 필드와 연관된 열을 제외한 모든 열은 EGL replace 문이 후속 업데이트를 위해 사용 가능합니다.
  • SQL 레코드에 대해 단 하나의 키 필드만 선언하면 open 문은 다음 조건을 충족하는 모든 행을 선택합니다.
    • 행이 SQL 레코드 파트의 레코드 특정 defaultSelectCondition 특성을 이행합니다.
    • SQL 테이블 키 열의 값은 SQL 레코드 변수의 키 필드에 있는 값보다 크거나 같습니다.
  • SQL 레코드의 키 필드 또는 복수 키 필드를 선언하지 않으면 레코드 특정 defaultSelectCondition이 유일한 검색 기준을 제공하며 open 문은 해당 기준을 충족하는 모든 행을 검색합니다.
  • 레코드 키 또는 기본 선택 조건을 지정하지 않으면 open 문은 테이블 내의 모든 행을 선택합니다.
  • 선택된 행은 정렬되지 않습니다.
EGL open 문은 SQL SELECT FOR UPDATE 문을 포함하는 커서 선언에 의해 생성된 코드에 표시됩니다. 다음 조건은 기본적으로 참입니다.
  • FOR UPDATE OF 절에는 읽기 전용 레코드 필드가 포함되지 않습니다.
  • 특정 레코드에 대한 SQL SELECT 문은 다음 명령문과 유사합니다.
      SELECT column01, 
             column02, ... 
             columnNN
      INTO   :recordField01,
             :recordField02, ...
             :recordFieldNN
      FROM   tableName 
      WHERE  keyColumn01 = :keyField01
      FOR UPDATE OF
             column01, 
             column02, ... 
             columnNN

EGL open 문에 임베디드 SQL 문을 지정하여 기본값을 대체할 수 있습니다(#sql 지시문 사용).

예제

다음 예제는 myCustomer라는 SQL 레코드 변수를 가정합니다.

  open myCustomerResults forUpdate for myCustomer;

  open x1 with
    #sql{
      SELECT customer_number,
             customer_name, 
             customer_balance
      FROM   Customer 
      WHERE  customer_number >= :myCustomer.customerNumber
      FOR UPDATE OF 
             :myCustomer.customerNumber, 
             :myCustomer.customerName,
             :myCustomer.customerBalance
    }

  open x2 with 
    #sql{
      SELECT customer_name, customer_balance
      FROM Customer
      WHERE customer_number = :myCustomer.customerNumber
    }
  for myCustomer;

  open x3 with
    #sql{
      call aResultSetStoredProc(:parameter)
    }
다음은 hold 키워드가 필요한 처리 플로우의 예제입니다.
  1. EGL open 문으로 커서를 선언하고 엽니다.
  2. EGL get next 문으로 행을 페치합니다.
  3. 루프에서 다음 조치를 수행합니다.
    1. 몇 가지 방식으로 데이터를 처리합니다.
    2. EGL replace 문으로 행을 업데이트합니다.
    3. sysLib.commit() 시스템 함수로 변경사항을 커미트합니다.
    4. EGL get next 문으로 다른 행을 페치합니다.

hold를 지정하지 않으면 커서가 더 이상 열려 있지 않으므로 3단계에서 네 번째 파트의 첫 번째 실행이 실패합니다.

오류 조건

다음 상황은 올바르지 않습니다.
  • SELECT에 필요한 절이 없는 임베디드 SQL문을 포함합니다. 필요한 절은 SELECT, FROM 및 FOR UPDATE OF(forUpdate 옵션을 지정하는 경우)입니다.
  • SQL 레코드 변수가 런타임에 존재하지 않는 열 또는 관련 레코드 필드와 호환되지 않는 열과 연관되었습니다.
  • 사용자가 forUpdate 옵션을 지정하고 코드가 다음과 같은 유형의 SQL 레코드 중 하나에 대해 open 문을 실행하려고 시도합니다.
    • 레코드 필드가 모두 읽기 전용인 SQL 레코드
    • 둘 이상의 SQL 테이블과 관련된 SQL 레코드
다음 조건이 둘 다 참인 경우에도 문제가 발생합니다.
  1. 업데이트를 위해 EGL open 문을 사용자 정의하면서 업데이트에 사용 가능한 특정 SQL 테이블 열을 표시하지 않습니다.
  2. open문과 관련된 replace 문이 열을 개정하려고 시도합니다.
다음과 같은 방법으로 이 문제를 해결할 수 있습니다.
  • EGL open 문을 사용자 정의하는 경우 SQL SELECT 문의 FOR UPDATE OF 절에 열 이름을 포함시키십시오.
  • EGL replace 문을 사용자 정의하는 경우 SQL UPDATE 문의 SET 절에서 열 참조를 제거하십시오.
  • EGL이 openreplace 문 둘 다를 위해 생성하는 암시적 SQL 코드를 승인하십시오.

호환성

각 관계형 데이터베이스 관리 시스템(RDBMS)에는 SQL의 자체 버전이 있습니다. 모든 구현에서 모든 SQL 명령을 사용할 수 있는 것은 아닙니다. 임베디드 SQL을 코딩하기 전에 RDBMS에 대한 문서를 확인하십시오.

표 1. open 및 SQL에 대한 호환성 고려사항
플랫폼 문제
Java 생성 hold 옵션은 JDBC 드라이버가 JDBC 3.0 이상을 지원하는 경우에만 Java 프로그램에서 사용할 수 있습니다.
CICS® 프로그램이 세그먼트화 모드로 실행되는 경우, converse 문은 CICS 트랜잭션을 종료하고, open 문에 hold 키워드가 사용된 경우에도 프로그램이 파일 또는 데이터베이스 위치를 보유하지 않도록 방지합니다.
IMS/VS 모든 converse 문이 세그먼트화 모드로 실행되는 경우, 이는 IMS™ 트랜잭션을 종료하고, open 문에 hold 키워드가 사용된 경우에도 프로그램이 파일 또는 데이터베이스 위치를 보유하지 않도록 방지합니다.
Cloudscape 또는 Derby 데이터베이스 EGL은 scrollforUpdate 플래그를 둘 다 사용하는 open 문을 지원하지 않습니다. 둘 중 하나만 사용할 수 있습니다.