Cursor는 SQL에서 행을 하나씩 순차적으로 처리해야 할 때 유용하게 사용됩니다. 일반적으로는 SQL에서 집합 단위로 데이터를 처리하지만, 일부 경우에는 각 행을 개별적으로 처리해야 할 필요가 있을 때 Cursor를 사용합니다. Cursor는 행 단위로 데이터를 탐색하면서 특정 작업을 수행할 수 있게 해줍니다.
기본 Syntax
Cursor를 사용하는 기본적인 흐름은 다음과 같습니다:
1. Cursor 선언
데이터를 탐색할 Cursor를 선언합니다.
DECLARE cursor_name CURSOR FOR
SELECT column1, column2, ...
FROM table_name
WHERE 조건;
2. Cursor 열기
선언한 Cursor를 열어서 사용할 수 있도록 합니다.
OPEN cursor_name;
3. Cursor에서 데이터를 가져오기
Fetch 문을 사용하여 Cursor에서 한 행씩 데이터를 가져옵니다.
FETCH NEXT FROM cursor_name INTO @변수1, @변수2, ...;
4. 반복문을 사용하여 처리
Cursor를 반복적으로 사용하여 각 행을 처리합니다. 이때, 반복문을 사용하여 데이터를 Fetch하고, 원하는 작업을 수행합니다.
WHILE @@FETCH_STATUS = 0
BEGIN
-- 행에 대해 수행할 작업
FETCH NEXT FROM cursor_name INTO @변수1, @변수2, ...;
END
5. Cursor 닫기
Cursor가 더 이상 필요하지 않으면 닫아줍니다.
CLOSE cursor_name;
6. Cursor 해제
Cursor와 관련된 메모리를 해제합니다.
DEALLOCATE cursor_name;
프로그램 사용 예시
아래는 예시 코드로, PATCH 테이블에서 각 패치를 순차적으로 처리하는 Cursor 예제입니다.
-- 변수 선언
DECLARE @patch INT;
-- 커서 선언
DECLARE patch_cursor CURSOR FOR
SELECT patch_id
FROM PATCH;
-- 커서 열기
OPEN patch_cursor;
-- 첫 번째 데이터를 가져오기
FETCH NEXT FROM patch_cursor INTO @patch;
-- 반복문을 사용하여 데이터를 처리
WHILE @@FETCH_STATUS = 0
BEGIN
-- 각 패치에 대한 처리 작업 (예시로 패치 로그를 기록한다고 가정)
INSERT INTO PATCH_LOG (patch_id, processed_at)
VALUES (@patch, GETDATE());
-- 다음 데이터를 가져오기
FETCH NEXT FROM patch_cursor INTO @patch;
END;
-- 커서 닫기
CLOSE patch_cursor;
-- 커서 해제
DEALLOCATE patch_cursor;
커서 사용의 필요성
Cursor는 SQL의 집합 연산으로 처리할 수 없는 순차적 작업이 필요할 때 유용합니다. 예를 들어, 각 행에 대해 독립적인 처리나 로직이 필요할 경우 Cursor를 사용하여 행별로 작업을 수행할 수 있습니다. 하지만 Cursor는 성능에 영향을 줄 수 있기 때문에, 가능한 경우 집합 연산을 사용하는 것이 좋습니다. 대량의 데이터를 처리할 때는 비효율적일 수 있으므로, 필요할 때만 사용하는 것이 권장됩니다.
프로그램 사용 예시 (확인용 스크립트)
아래는 커서를 사용하여 각 사용자의 데이터를 처리하고, 처리 결과를 확인하는 스크립트 예시입니다.
-- 변수 선언
DECLARE @user_id INT, @user_name NVARCHAR(50);
-- 커서 선언
DECLARE user_cursor CURSOR FOR
SELECT user_id, user_name
FROM USERS;
-- 커서 열기
OPEN user_cursor;
-- 첫 번째 데이터를 가져오기
FETCH NEXT FROM user_cursor INTO @user_id, @user_name;
-- 반복문을 사용하여 데이터를 처리
WHILE @@FETCH_STATUS = 0
BEGIN
-- 처리 로직 (예: 사용자에게 이메일을 보내는 로직을 추가할 수 있음)
PRINT 'Processing user: ' + @user_name;
-- 다음 데이터를 가져오기
FETCH NEXT FROM user_cursor INTO @user_id, @user_name;
END;
-- 커서 닫기
CLOSE user_cursor;
-- 커서 해제
DEALLOCATE user_cursor;
이제 Cursor의 사용법과 주의사항을 이해하고, 필요한 상황에서 사용할 수 있게 되었습니다. Cursor는 매우 유용한 도구이지만, 성능에 주의하며 적절하게 사용하는 것이 중요합니다.