본문 바로가기
Programming/DB (SQL)

[SQL Server] Chapter 17. 커서

by 곰네Zip 2014. 12. 10.

*본 포스팅은 개인의 학습 내용을 정리한 것입니다.

 

- 커서 : 각 행 별로 작업을 수행하는데 유용하다. 쿼리로 다음과 같은 작업을 수행할 수 있다.

       SQL문을 수행 시, 결과에 대해 집합(table형태)으로 반환한다. 커서는 이러한 결과에 대해 한 행 단위로 처리하게함

  1) 결과 집합의 특정 행에 위치를 지정할 수 있다.

  2) 결과 집합의 현재 위치에서 한 행 또는 행 블럭을 검색

  3) 결과 집합의 현재 위치에서 행에 대한 데이터 수정

 

1. 커서 유형

 (1) 정적커서

   - 결과 집합을 tempdb에 복사본을 만들어 사용함. 원본에 변경이 생겨도 알 수 없다. 항상 읽기 전용

 (2) 동적커서

   - 정적커서와 대응되는 개념. 현재 위치의 키 값만 tempdb에 가짐. 원본의 모든 변동은 결과집합에 반영되고, 커서에서

    행을 읽을 때 마다 해당 내용의 변경사항을 읽어올 수 있다.

 (3) 키 집합 커서

   - 키 집합만을 tempdb에 복사하여 사용. 각 키가 가리키는 행의 내용의 변동사항은 인지할 수 있다. 하지만, 키가 추가

    되거나 삭제된 경우는 인지할 수 없다.

 (4) 정방향 전용 커서

   - 스크롤 지원 안됨. 순차적으로 행의 데이터를 가져오는 것만 지원한다.

(참조: http://msdn.microsoft.com/ko-kr/library/ms130910.aspx)

 

2. 커서 사용 절차

 - 커서는 다음과 같이 5단계로 동작한다.

   DECLARE - OPEN - FETCH - CLOSE - DEALLOCATE

 (1) DECLARE

   - 커서를 선언한다

   1) ANSI문법

 DECLARE <커서이름> [INSENSITIVE] [SCROLL] CURSOR FOR

 <SELECT구문>

 [FOR { READONLY | UPDATE [ OF <컬럼명>[, ...n] } ]

    - INSENSITIVE : 정적 커서를 사용한다.

    - SCROLL : 모든 인출옵션(FIRST,LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE)를 사용할 수 있다. 해당 키워드가

     없으면 NEXT만 가능하다.

    - SELECT구문 : 일반적인 SELECT구문

    - READONLY : 커서를 통한 데이터 변경을 방지하는 옵션

 

   2) T-SQL문법

 DECLARE <커서이름> CURSOR [ LOCAL | GLOBAL ]

 [ FORWARD_ONLY | SCROLL ]

 [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]

 [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]

 [ TYPE_WARNING ]

 FOR <select구문>

 [FOR UPDATE [ OF <컬럼명> [, ... n] ] ]

     - LOCAL, GLOBAL : LOCAL은 커서가 만들어진 일괄처리, 저장프로시저, 트리거 내에서만 유효하다. 전역의 경우

      다른 프로시저나 일괄처리에서 사용 가능하다. 하지만 세션을 넘어서 사용하는 것은 안됨

     - STATIC, KEYSET, DYNAMIC

       커서의 유형을 정의. 커서의 유형은 위에서 설명.

 커서유형

 tempdb의 복사본

 변경자료 반영

 메모리 사용

 스크롤 비용

 STATIC

 전체

 모두 반영 안됨

 많음

 적음

 KEYSET

 키값 (전체의 키값)

 키값은 반영안됨

 중간

 중간

 DYNAMIC

 현재 키값

 모두 반영됨

 적음

 많음

     - FORWARD_ONLY, SCROLL : SCROLL지정시 모든 인출옵션 사용가능. 아니면 NEXT만 가능

       > 커서유형을 지정하지 않은 채, FORWARD_ONLY만 지정 : DYNAMIC커서

       > 커서유형 지정하고 스크롤 옵션 지정하지 않을 경우 : SCROLL

       > STATIC,DYNAMIC,KEYSET이 아닌 커서에서 지정하지 않을경우 : FORWARD_ONLY가 기본

     - FAST_FORWARD : 성능 최적화를 한 FORWARD_ONLY, READ_ONLY커서를 지정

     - READ_ONLY : 커서를 이용한 내용 수정 방지

     - SCROLL_LOCKS : 커서로 행을 읽을 때, 수정을 위해 행을 잠금. FAST_FORWARD지정시 잠금 불가

     - OPTIMISTIC : 커서로 행을 읽은 후, 해당 행이 업데이트 된 경우, 커서를 이용한 수정이 실패하도록 함

     - TYPE_WARNING : 커서형식이 다른 형식으로 묵시적변환이 된 경우 경고 메시지를 표출

     - SELECT구문 : 커서의 결과 집합을 정의하는 SQL구문

     - UPDATE [ OF <컬럼명>[... , n] : 업데이트 가능한 컬럼을 지정하고, 그열만 수정할 수 있도록 제한 해제.

 

 (2) OPEN : DECLARE CURSOR, SET cursor_variable에서 지정된 T-SQL문을 사용하여 SQL서버를 열고 커서를 채운다.

 OPEN <커서이름>

 

 (3) FETCH : 커서에서 행을 얻어옴. SCROLL옵션이랑 같이 사용한다.

 FETCH <FETCH옵션> <커서이름>

  - FETCH옵션에 따라 커서에 결과를 받아온다. 받아온 결과는 @@FETCH_STATUS함수로 결과를 확인할 수 있다.

    아래는 커서 옵션에 대한 기술이다. 

 커서옵션

 설명

 FIRST

 커서의 첫 번째 행을 반입

 LAST

 커서의 마지막 행을 반입

 NEXT

 반입된 마지막 행의 다음 행을 반입

 PRIOR

 반입딘 마지막 행의 이전 행을 반입

 ABSOLUTE n

 첫 번째 행으로부터 n번째 있는 행을 반입. n이 음수이면 끝에서부터 n번째. 0이면 반입안함

 RELATIVE n

 마지막 반입된 행으로부터 n번째(음수이면 앞으로 n번째) 행을 반입. 0이면 같은 행 반입

 

 (4) CLOSE : 현재 결과 집합을 해제하고, 커서가 위치한 행에 대한 잠금을 해제한 후 커서를 닫는다.

 CLOSE <커서이름>

 

 (5) DEALLOCATE :  커서의 참조를 제거한다. 마지막 참조가 해제될 경우. SQL Server에서 해당 커서 데이터구조를 해제한다.

 DEALLOCATE <커서이름>

 

4. 커서의 자동 형 변환

 - 선언된 유형의 커서를 지원하기 어려운 T-SQL문의 경우 SQL서버에서 자동으로 변경된다.

 단계

 변화원인

 전진전용

 빠른전진전용

 키 집합

 동적

 다음단계

 1

 커서가 TOP절을 사용하여 뷰를 참조할 때

 정적

 정적

 정적

 정적

 완료

 2

 쿼리의 FROM절이 테이블을 참조하지 않을 때

 정적

 

 정적

 정적

 완료

 3

 쿼리에서 선택목록집계, GROUP BY, UNION, DISTINCT, HAVING등을 포함할 때

 정적

 

 정적

 정적

 완료

 4

 쿼리가 트리거에 있는 삽입(삭제)된 테이블 참조시

 정적

 

 정적

 정적

 완료

 5

 쿼리가 트리거테이블을 다른 테이블에 조인할 때

 

 정적

 

 

 완료

 6

 READ_ONLY지정하지 않았을 때

 

 정적

 

 

 8

 7

 ODBC API서버커서가 text,ntext,image참조할 때

 

 정적

 

 

 8

 8

 쿼리가 내부작업 테이블을 생성할 때

 키집합

 

 

 키집합

 10

 9

 쿼리가 연결된 서버의 원격 테이블을 참조할 때

 키집합

 키집합

 

 키집합

 10

 10

 쿼리가 고유 인덱스 없이 하나 이상의 테이블을 참조할 때

 

 

 정적

 

 완료

 11

 커서가 ntext,text,image컬럼을 참조하고, 쿼리에 TOP절이 있을 때

 

 키집합

 

 

 완료

 

 (1) 서버 사이드 커서의 장점

  - SQL 서버의 커서는 모두 서버사이드 커서임. 서버사이드의 장점은 다음과 같다

   1) 자원의 사용 : 클라이언트 커서는 서버의 모든 데이터를 캐시 메모리로 가져온다. 그러나 서버에서는 적정한 블럭만 FETCH 해서 사용하므로 자원 낭비가 적다. 작업할 자료가 크면 서버 커서가 더 효율적

   2) 부가적인 커서형 : 클라이언트는 읽기전용, 정적 커서만 지원. 서버는 키셋과 동적커서를 지원한다.

   3) 다중커서 사용 : 여러 커서를 사용해야 할 경우 하나의 세션에서 모두 처리가 가능하다.

 

- 출처 : SQL Server advanced programming

반응형

댓글