[펌] [사용성] COMMIT 과 SELECT 관계 정립

altibase 는 현재 5.1.5.x 이하의 모든 버전 기준.
FETCH LOOP 내에서 COMMIT / ROLLBACK 수행시 SELECT 결과 SET도 해제되는 문제가 있음.


DB2 사례
---------------------------
From : http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/r0000937.htm

DECLARE CURSOR

DECLARE CURSOR문은 커서를 정의합니다.

호출

대화식 SQL 기능에서 대화식 실행의 형태를 나타내는 인터페이스를 제공하더라도,이 명령문은 응용프로그램 내에만 임베드될 수 있습니다. 이 명령문은 실행문이 아니며 동적으로 준비될 수 없습니다.

권한 부여

이 용어는 『커서의 SELECT문』은 권한 부여 규칙을지정하는 데 사용됩니다.커서의 SELECT문은 다음 중 하나입니다.

  • statement-name에 의해 식별된 준비된 select문
  • 지정된 select-statement

커서의 SELECT문에서 식별된(직접적으로 또는 별명을 사용하여)각 테이블 또는 뷰마다, 명령문의 권한 부여 ID로 보유되는특권에는 최소한 다음 중 하나가 포함되어야 합니다.

  • select-statement에 식별되는 각 테이블이나 뷰에 대해
    • 테이블이나 뷰에서의 SELECT 특권 또는
    • 테이블 또는 뷰에서의 CONTROL 특권
  • SYSADM 또는 DBADM 권한

4 select-statement에 SQL 데이터 변경문이 있는 경우4 해당 명령문의 권한 요구사항이 DECLARE CURSOR문에도 적용됩니다.

statement-name이 지정된 경우:

  • 명령문의 권한 부여 ID는 런타임 권한 부여 ID입니다.
  • 권한 부여 점검은 select문이 준비될 때 수행됩니다.
  • 커서는 select문이 올바로 준비되지 않으면 열리지 않습니다.

select-statement이 지정된 경우:

  • GROUP 특권이 점검되지 않습니다.
  • 명령문의 권한 부여 ID는 프로그램 준비시 지정되는 권한 부여 ID입니다.
구문
구문 도표 읽기시각적 구문 도표 생략>>-DECLARE--cursor-name--CURSOR--+-----------+------------------>
'-WITH HOLD-'

>--+----------------------------+--FOR--+-select-statement-+---><
| .-TO CALLER-. | '-statement-name---'
'-WITH RETURN--+-----------+-'
'-TO CLIENT-'

설명
cursor-name
소스 프로그램이 실행될 때 작성된 커서의 이름을 지정합니다.이름은 소스 프로그램에서 선언된 다른 커서의 이름과 동일해선 안됩니다.커서는 사용하기 전에 열려 있어야 합니다.
WITH HOLD
여러 작업 단위에서 자원을 유지보수합니다. WITH HOLD 커서 속성의 영향은 다음과 같습니다.
  • COMMIT로 끝나는 작업 단위(UOW)의 경우
    • WITH HOLD로 정의된 열린 커서는 열린 채로 있습니다. 커서는결과 테이블의 다음 논리 행 전에 위치됩니다.

      DISCONNECT문이 WITH HOLD 커서를 갖는 연결에 대해 COMMIT문다음에 발행된 경우, 보유된 커서는 명시적으로 닫혀 있어야합니다. 그렇지 않으면, 연결은 작업을 수행한 것(SQL문이발행되지 않았어도 열린 WITH HELD 커서를 지님으로써)으로간주되어 DISCONNECT문이 실패하게 됩니다.

    • 열려 있는 WITH HOLD 커서의 현재 커서 위치를 보호하기위한 잠금을 제외한 모든 잠금이 해제됩니다. 테이블에 대한잠금과, 병렬 환경의 경우 커서가 현재 위치한 행에 대한잠금은 그대로 유지됩니다. 패키지와 동적 SQL 섹션(있을경우)에 대한 잠금은 그대로 유지됩니다.
    • 다음은 COMMIT 요청 바로 다음에 오는 WITH HOLD 정의되는커서에 대한 유효한 조작입니다.
      • FETCH: 커서의 다음 행을 페치합니다.
      • CLOSE: 커서를 닫습니다.
    • UPDATE 및 DELETE CURRENT OF CURSOR는 같은 작업 단위 내에서패치되는 행에 대해서만 유효합니다.
    • LOB 로케이터는 해제됩니다.
    • 4 행 설정은 다음과 같이 수정됩니다.4 4
        4
      • 데이터 변경문
      • 4
      • 열린 WITH HOLD 커서에 임베드된 SQL 데이터를 수정하는 루틴
      4 이 커미트됩니다.
  • ROLLBACK로 끝나는 작업 단위의 경우
    • 열린 커서는 모두 닫힙니다.
    • 작업 단위에서 획득된 모든 잠금은 해제됩니다.
    • LOB 로케이터는 해제됩니다.
  • 특수 COMMIT의 경우
    • 패키지는 패키지를 바인딩하여 명시적 또는 내재적으로재작성될 수 있습니다. 패키지의 유효성이 검사된 후 처음으로참조될 때 동적으로 재작성되었기 때문입니다. 패키지의리바인드중 보유된 모든 커서가 닫힙니다. 이는 후속 실행에서오류를 야기할 수도 있습니다.
WITH RETURN
이 절은 커서가 프로시저로부터의 결과 세트로사용됨을 나타냅니다.WITH RETURN은 DECLARE CURSOR문이 프로시저의소스 코드와 함께 포함되는 경우에만 관련됩니다. 다른 경우에는프리컴파일러가 이 절을 사용할 수 있으나 아무 효과도 없습니다.

SQL 프로시저내에서 SQL 프로시저 종료시에도 여전히 열려 있는WITH RETURN절을 사용하여 선언된 커서는 SQL 프로시저로부터의결과 세트를 정의합니다.SQL 프로시저 내의 다른 모든 열린 커서는SQL 프로시저가 종료될 때 닫힙니다.외부 프로시저(LANGUAGE SQL을 사용하여 정의되지 않은) 내에서는 모든 커서의 디폴트가 WITH RETURN TO CALLER입니다.그러므로 프로시저를 종료할 때 열려 있는 모든 커서는 결과 세트로 간주됩니다.

TO CALLER
커서가 결과 세트를 호출자에게 리턴할 수 있도록 지정합니다. 예를 들어, 호출자가 다른 프로시저인 경우 결과 세트는 해당프로시저로 리턴됩니다. 호출자가 클라이언트 응용프로그램인 경우결과 세트는 클라이언트 응용프로그램으로 리턴됩니다.
TO CLIENT
커서가 결과 세트를 클라이언트 응용프로그램으로리턴할 수 있도록 지정합니다. 이 커서는 중간 중첩된 프로시저에게는 보이지 않습니다.함수나 메소드가 직간접적으로 프로시저를 호출한 경우에는결과 세트가 클라이언트에게 리턴되지 않고 프로시저가 완료되면 커서가 닫힙니다.
select-statement
커서의 SELECT문을 식별합니다.select-statement은 매개변수 표시문자를 포함해서는 안되나, 호스트 변수에 대한 참조는 포함할 수 있습니다.호스트 변수의 선언은 소스 프로그램에서 DECLARECURSOR문 앞에 있어야 합니다.
statement-name
statement-name 커서의 SELECT문은 커서가 열릴 때명령문 이름으로 식별되는 준비된 SELECT문입니다. statement-name은 소스 프로그램의 다른 DECLARE CURSOR문에 지정된statement-name과 같으면 안됩니다.

prepared SELECT문에 대한 설명은 『PREPARE』를 참조하십시오.

참고
  • 다른 프로그램 또는같은 프로그램내의 다른 소스 파일로부터 호출되는 프로그램은 호출하는 프로그램이열어 놓은 커서를 사용할 수 없습니다.
  • SQL이 아닌 다른 LANGUAGE로 중첩되지 않은 프로시저는WITH RETURN절없이 DECLARE CURSOR가 지정되고 커서가 프로시저에서 열려 있는경우 디폴트 동작으로 WITH RETURN TO CALLER를 가지게 됩니다. 이는 이전 버전의프로시저로 하여금 리턴 결과 세트를 적용 가능한 클라이언트 응용프로그램으로리턴할 수 있는 호환성을 제공합니다. 이러한 동작을 피하려면 해당 프로시저에서열려 있는 모든 커서를 닫으십시오.
  • 커서의 SELECT문에 CURRENT DATE, CURRENT TIME 또는 CURRENTTIMESTAMP가 포함되어 있으면, 이 특수 레지스터에 대한 모든참조사항은 각 FETCH에서 같은 각각의 날짜 시간 값을 생성합니다.이 값은커서가 열릴 때 결정됩니다.
  • 데이터의 효율적인 처리를 위해, 데이터베이스 관리자는 리모트서버로부터 데이터를 검색할 때 읽기 전용 커서에 대해 데이터를블록화할 수 있습니다. FOR UPDATE절을 사용하면, 데이터베이스관리 프로그램에서 커서가 갱신 가능 여부를 쉽게 결정할 수있습니다. 갱신 가능성은 액세스 경로 선택을 결정할 경우에도사용됩니다. 커서가 위치지정된 UPDATE나 DELETE문에서사용되지 않을 경우 FOR READ ONLY로 선언되어야 합니다.
  • 열린 상태의 커서는 결과 테이블과 그 테이블의 행에 상대적인위치를 지시합니다. 테이블은 커서의 SELECT문에 의해 지정된결과 테이블입니다.
  • 커서는 다음 각각의 조건이 만족되는 경우 삭제 가능 합니다.
    • 외부 fullselect의 각 FROM절이 OUTER절을 사용하지 않고 하나의기본 테이블이나 삭제 가능 뷰를 식별하는 경우(중첩된 또는 공통 테이블 표현식이나별칭은 식별할 수 없습니다.)
    • 외부 fullselect에 VALUES절이 포함되지 않는 경우
    • 외부 fullselect에 GROUP BY절 또는 HAVING절이 포함되지 않는 경우
    • 외부 fullselect에 선택 목록 내의 컬럼 함수가 포함되지 않는 경우
    • 외부 fullselect에 UNION ALL 예외가 있는 SET 조작(UNION,EXCEPT 또는 INTERSECT)이 포함되지 않는 경우
    • 외부 fullselect의 선택 목록에 DISTINCT가 포함되지 않는 경우
    • 4 외부 fullselect에 ORDER BY절이 포함되어 있지 않고(ORDER BY절이 뷰에 중첩되어 있는 경우라도)4 FOR UPDATE절은 지정되어 있지 않습니다.
    • select-statement에 FOR READ ONLY절이 포함되지 않는 경우
    • 4 외부 fullselect의 FROM 절에 data-change-table-reference가 포함되지 않는 경우
    • 다음 중 하나 이상이 만족되는 경우
      • FOR UPDATE절이 지정됩니다.
      • 4 STATICREADONLY 바인드 옵션이 YES가 아닌 경우4 해당 커서는 정적으로 정의됩니다.
      • LANGLEVEL 바인드 옵션이 MIA 또는 SQL92E인 경우

    커서와 연관된 외부 fullselect의 선택 목록에 있는 컬럼은 다음 각각이 만족되는 경우 갱신 가능 합니다.

    • 커서가 삭제 가능한 경우
    • 컬럼이 기본 테이블의 컬럼을 해석하는 경우
    • LANGLEVEL 바인드 옵션이 MIA이고, SQL92E 또는 선택문에 FOR UPDATE절이포함되는 경우(해당 컬럼을 FOR UPDATE절에 명시적으로 또는 내재적으로 지정해야 합니다).

    커서가 삭제 불가능한 경우, 읽기 전용 입니다.

    커서는 다음 조건의 각각이 만족되는 경우 앰비규어스 합니다.

    • 선택문이 동적으로 준비된 경우
    • 선택문에 FOR READ ONLY절 또는 FOR UPDATE절이 포함되지 않는 경우
    • LANGLEVEL 바인드 옵션이 SAA1인 경우
    • 그렇지 않으면, 커서가 삭제 가능 커서의 조건을 만족하는 경우

    앰비규어스 커서는 BLOCKING 바인드 옵션이 ALL인 경우 읽기 전용으로 간주되고,그렇지 않으면, 갱신 가능으로 간주됩니다.

  • CLI를 사용하여 작성된 응용프로그램이 호출한 프로시저의커서는 클라이언트 응용프로그램으로 직접 리턴된 결과 세트를 정의하는데 사용될 수 있습니다. SQL 프로시저의 커서는 WITH RETURN절을 사용하여 정의된 경우에만호출하는 SQL 프로시저로 리턴될 수 있습니다.
  • WITH HOLD로 선언된 커서에서 직간접적으로 호출한 루틴에 선언된 커서는 WITH HOLD 옵션을 상속하지 않습니다.따라서 루틴의 커서가 명시적으로 WITH HOLD로 정의되어 있지 않으면 응용프로그램의COMMIT가 커서를 닫습니다.

    다음 응용프로그램과 두 개의 UDF를 고려하십시오.

    Application:

    DECLARE APPCUR CURSOR WITH HOLD FOR SELECT UDF1() ...
    OPEN APPCUR
    FETCH APPCUR ...
    COMMIT

    UDF1:

    DECLARE UDF1CUR CURSOR FOR SELECT UDF2() ...
    OPEN UDF1CUR
    FETCH UDF1CUR ...

    UDF2:

    DECLARE UDF2CUR CURSOR WITH HOLD FOR SELECT UDF2() ...
    OPEN UDF2CUR
    FETCH UDF2CUR ...

    응용프로그램이 APPCUR 커서를 페치(fetch)한 후에는 세 커서가 모두 열려 있습니다.APPCUR 커서는 WITH HOLD로 선언되어 있기 때문에 응용프로그램이 COMMIT문을 발행할 때APPCUR 커서는 계속 열려 있습니다.그러나 UDF1에서는 UDF1CUR 커서가 WITH HOLD 옵션으로 정의되어 있지 않기 때문에UDF1CUR 커서가 닫힙니다.UDF1CUR 커서가 닫히면 해당 select문에 있는 모든 루틴 호출이 완료되고,최종 호출을 수신하도록 정의되어 있으면 최종 호출을 수신합니다.UDF2가 완료되면 UDF2CUR가 닫힙니다.

예:

예1:  DECLARE CURSOR문은 커서 이름 C1을 SELECT의 결과와 연관시킵니다.

  EXEC SQL  DECLARE  C1 CURSOR FOR 
SELECT DEPTNO, DEPTNAME, MGRNO
FROM DEPARTMENT
WHERE ADMRDEPT = 'A00';

4 예 2:  4 EMPLOYEE 테이블을 변경하여, 연봉을 기초로 주급을 계산한4 WEEKLYPAY 컬럼을 추가한다고 가정하십시오.4 커서를 선언하여, 삽입되는 행에서 시스템 생성 컬럼 값을 검색합니다.4

4
   EXEC SQL DECLARE  C2 CURSOR FOR 
4 SELECT E.WEEKLYPAY
4 FROM NEW TABLE
4 (INSERT INTO EMPLOYEE
4 ( EMPNO, FIRSTNME, MIDINIT, LASTNAME, EDLEVEL, SALARY )
4 VALUES( '000420', 'Peter', 'U', 'Bender', 16, 31842 ) AS E;

이 글과 관련있는 글을 자동검색한 결과입니다 [?]

by 오서비네 | 2009/02/26 13:06 | DBMS | 트랙백

<< 이전 페이지     다음 페이지 >>