본문 바로가기

데이터베이스/MSSQL

[기본] Cursor

커서를 왜 사용하는가!

자 이번 이야기는 상상력을 많이 가지고 계셔야 합니다. 천천히 머리속으로 상황을

생각 하시면서 따라와 보세요.

제가 아는 동생중에 닉네임을 차마 밝힐 수 없는 "꼬마"모 로 불리우는 모"악마"님이 계십니다.

현재 N도 있고.. 아울러 사회적인 지위를 생각해 닉네임을 못 밝히는 것을 부디 양해해 주세요.

-_-;;

 

이동생은 아주 능력있는 동생 입니다. Tae**모사이트의 ***yo모사이트 ASP 시삽이기도

합니다. 아주 능력 있지요.. 종종 벙개 모임을 참석 하신다면.. 이분의 몸매가 기억

나실 겁니다.. 머.. 공기 유체 에너제틱 역학적으로.. 아주.. 음.. 그렇습니다.

뭐.. 키요?..  버스에 타면.. 음..  자연 스럽게... 버스 손잡이를 잡을.. 수..가... 음.. 습니다.

네.. 그렇습니다..  아.. 더 중요한 사항으로.. 음식과 관계가 깊기 때문에.. 음...

..  그래서!!!!  결론이...!!!  이친구는 훈련소를 매우 높은 성적으로 수료하고!!!!!

특공연대 대신.. 우체국에 근무하게 되었습니다.

아~~!!  우체부아저씨!!!  모든 국민학생(초등학생)의 선망의 대상... 편지를 집까지 배달

해 주는.. 그 멋진 우체부 아저찌가 되나부다..  - 아니죠...

우체국 안에서.. 모아진 우편물을.. 분류하는!!! 직업 전선!!  - 실수군요.. - 군대 전선.!!

에 뛰어들게 됩니다..  자..  우편물이 가득~~~ 쌓여 있습니다. 그리고 앞에는

싸인펜과 전국 우체국으로 나가는 다닥다닥 벌집처럼 붙어 있는 나무로된 박스가 있습니다.

우편물의 주소를 보고 저 박스중 한군데에 넣어야 우편물이.. 이동이 되는 것이지요~

이친구의 일은 복잡합니다.

 1. 쌓여있는 우편물중 맨 위에것 하나를 집는다.

2. 우편번호와 주소를 확인한다.

2-1. 우편번호가 있다면 체크 표시를 싸인펜으로(이용도 입니다.) 한후 해당 지역의

       나무 박스에 넣는다.

2-2. 우편 번호가 없다면 체크표시를 한후 싸인펜으로(아주 유용!) 우편번호를 우편번호

       책에서 찾아(대부분 머리속에 있음) 쓴후 나무 박스에 넣는다.

2-3. 이 작업을 쌓여 있는 우편물이 없을 때까지 계속한다.

 

"신이시여!!! 어찌하여 저에게 이런 시련을 주시나이까!!!" 라고 외치며 기나긴 18개월.!!

간의 시간을 이 우체국에서 젊음을 불태우게 되었습니다. - 당연히 후배가 가장 싫어 하는

날은? - 

1. 크리스마스 - 지옥과 같은 날 - 야근 기본

2. 연말 - 망년회는 커녕 망년 폭발 젊음 불사르기

3. 연초 - 1월 1일 출근은 기본

의 생활을 하게 되었습니다.

 

커서와 후배가 뭔 상관이냐구요?? - 있습니다.. 것두 아주 많이...

1. 쌓여있는 우편물중 맨 위에것 하나를 집는다.

2. 우편번호와 주소를 확인한다.

2-1. 우편번호가 있다면 체크 표시를 싸인펜으로(이용도 입니다.) 한후 해당 지역의

       나무 박스에 넣는다.

2-2. 우편 번호가 없다면 체크표시를 한후 싸인펜으로(아주 유용!) 우편번호를 우편번호

       책에서 찾아(대부분 머리속에 있음) 쓴후 나무 박스에 넣는다.

2-3. 이 작업을 쌓여 있는 우편물이 없을 때까지 계속한다.

자 이 작업 입니다.!

 

SQL 서버의 데이터 처리를 다시 생각해 봅시다..

SQL서버는 모든 작업을 컬럼(열)기반으로 처리 합니다.

작업의 처리 방식은 컬럼에 대해서 수행 된다는 의미 입니다.

WHERE절은? 컬럼의 특정 값에 대해서 로우(행)을 선택할 뿐입니다.

여기서 또 정신적으로 많이 불안하신 분들은 이런 생각을 하실 겁니다.

identity로 컬럼을 잡은후.. 

1. identity값이 가장 낮은 녀석을 SELECT 한다.

2. identity 값을 + 1한 녀석을 SELECT 한후 가져온다. 없다면? 또 +1 한 녀석을 가져온다.

3. Max 값까지 한다. 

이렇게 생각하시는 분도 계실 겁니다. 천천히 몇번을 전체 테이블을 뒤져서 처리해야

할지 생각해 보세요.

 

그렇다면..!!!

위의 우체국의 일중에서.. 쌓여있는 우편물 = 테이블의 로우(행) 이라고 생각해 보세요.

우편물(로우)을 하나 가져와서 우편번호 체크(어떠한 처리작업) 후 

해당하는 나무박스(테이블이나 저장소)에 넣는 작업을 우편물(로우)가 없을 때까지 계속

합니다.

 

즉!!  커서는 로우를 기반으로 하는 작업이 된다!!! 라는 것입니다.

저러한 로우를 하나 SELECT해서 여러가지 처리를 한후 어떠어떠한 작업을 한다~~

이것을 가능하게 하는 것이 바로!!! 커서 입니다.

물론 SQL구문만을 가지고 어거지로 어찌어찌 한다면~~ 가능할 겁니다.

하지만 커서를 이용하시면 훨씬 빠르고 간단히 저러한 처리를 가능하게 할 수 있습니다.

 

자 조금 이해가 가시나요~~

이제 커서를 왜 사용하는지.. 왜 저런 이야기를 주저리주저리 떠든건지 이해가 가실 겁니다.

 

커서는 

1. 커서 선언(Declare)

2. 커서 오픈(Open)

3. 데이터 행 가져오기(Fetch)

4. 커서 클로즈(Close)

5. 커서 선언 제거(Deallocate)

로 이루어 집니다.

 

간단히 샘플을 이용해 하나의 작업을 수행해 보도록 하지요.

샘플 데이터를 생성해 보도록 합시다.

 


CREATE TABLE 우편물(
번호 int identity(1,1)
, 우편번호 varchar(3)
, 우편주소 varchar(6)
)

INSERT INTO 우편물(우편번호, 우편주소) 
VALUES('001', '코난동')
INSERT INTO 우편물(우편번호, 우편주소) 
VALUES('002', '악마동')
INSERT INTO 우편물(우편번호, 우편주소) 
VALUES('003', '악어동')
INSERT INTO 우편물(우편번호, 우편주소) 
VALUES('004', '태오동')
INSERT INTO 우편물(우편번호, 우편주소) 
VALUES('', '코난동')
INSERT INTO 우편물(우편번호, 우편주소) 
VALUES('', '악마동')

CREATE TABLE 우편번호(
우편번호 varchar(3)
, 우편주소 varchar(6)
)

INSERT INTO 우편번호 VALUES('001', '코난동')
INSERT INTO 우편번호 VALUES('002', '악마동')
INSERT INTO 우편번호 VALUES('003', '거북동')
INSERT INTO 우편번호 VALUES('004', '태오동')
INSERT INTO 우편번호 VALUES('005', '악어동')

SELECT * FROM 우편물
SELECT * FROM 우편번호

 

자 어떠한 데이터인지 감이 좀 잡히시지요? ^_^

데이터를 보시면? 대부분의 사람들이 우편번호를 잘못 넣거나 아예 넣지 않습니다.

그래서 우리의 앙마 동생이 필요했던 거지요. 또한 팬시 봉투를 쓸 경우 자동화 처리가

안되기 땜시 앙마 동생이 일이 더 많았다고 합니다. - 규격 봉투를 사용합시다!!

먼저 악어동은 005번인데..  003번으로 잘 못 넣었습니다.

다음으로 맨 마지막의 두건은? 아예 우편 번호를 넣지 않았습니다.

 

이를 어떻게 처리하면 좋을까요? 바로 커서를 사용해 완빵으로 마무리 지어 보지요.

 


--커서 선언
DECLARE cur_konan_Test CURSOR 
FOR
SELECT 번호, 우편번호, 우편주소 FROM 우편물

--커서 오픈
OPEN cur_konan_Test

--변수 선언
DECLARE @v_번호 INT
DECLARE @v_우편번호 VARCHAR(3)
DECLARE @v_우편주소 VARCHAR(6)

--첫 로우 FETCH
FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

WHILE @@FETCH_STATUS = 0
BEGIN
--FETCH된 데이터를 tempdb에 삽입
UPDATE 우편물 
SET 우편번호 = (SELECT 우편번호 FROM 우편번호 WHERE 우편주소 = @v_우편주소)
WHERE 번호 = @v_번호

--다음 로우 FEETCH - 루프
FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소
END

--커서 CLOSE
CLOSE cur_konan_Test

--커서 DEALLOCATE
DEALLOCATE cur_konan_Test
GO

 

자 우편물 테이블에서 데이터를 조회해 보세요.

어떠십니까~~~

자 지금은 간단히 수작업으루 해두 되겠네..머...

만약 회사 회원이 10만명이라면? 아울러 전국 수만개 우편번호에서 찾아야 된다면?

충분히 닭이 될 수 있는 저런 작업을 순식간에 커서를 이용해 마무리 지을 수 있겠지요?

바로 이것이 커서를 사용하는 목적 입니다.

 

자 다음장에서 천천히 설명과 샘플을 보여 드리도록 하지요.

왜 커서를 사용하는지만 느끼시면 성공하신 겁니다.